<template>
  <div
    class="ai-chat-page flex h-[calc(100vh-60px)] bg-gray-100 dark:bg-gray-900"
  >
    <!-- 左侧边栏 -->
    <div
      class="w-60 bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 flex flex-col overflow-hidden"
    >
      <!-- 标题 -->
      <div
        class="px-4 py-3 border-b border-gray-200 dark:border-gray-700 shrink-0"
      >
        <h1 class="text-lg font-medium text-center">贵港文旅+ AI助手</h1>
        </div>

      <!-- 新建对话按钮 -->
      <div class="px-4 py-2 shrink-0">
        <el-button
          type="primary"
          class="w-full flex items-center justify-center !bg-gradient-to-r from-primary-500 to-primary-600"
          @click="createNewChat"
        >
          <el-icon class="mr-1"><Plus /></el-icon>
          新建对话
        </el-button>
      </div>

      <!-- 搜索历史对话 -->
      <div class="px-4 py-2 shrink-0">
          <el-input
            v-model="searchQuery"
          placeholder="搜索历史对话..."
          clearable
          prefix-icon="Search"
          class="w-full"
          />
        </div>

      <!-- 批量管理按钮 -->
      <div class="px-4 py-1 shrink-0 flex justify-between items-center">
        <el-checkbox 
          v-model="batchMode" 
          class="text-xs text-gray-500"
          @change="toggleBatchMode"
        >
          批量管理
        </el-checkbox>
        <div v-if="batchMode" class="flex space-x-2">
          <el-button 
            size="small" 
            @click="selectAll"
            :disabled="!filteredChatHistory.length"
          >
            全选
          </el-button>
          <el-button
            size="small" 
            type="danger" 
            @click="batchDeleteChats"
            :disabled="!selectedChats.length"
          >
            删除
          </el-button>
        </div>
      </div>

      <!-- 历史对话列表 -->
      <div
        ref="messageContainer"
        class="flex-1 overflow-y-auto px-2 custom-scrollbar"
      >
        <div
          v-for="chat in filteredChatHistory"
          :key="chat.id"
          class="chat-item group p-3 rounded-lg mb-2 cursor-pointer hover:bg-gray-50 transition-colors flex items-center"
          :class="{ 'bg-gray-50': currentChat?.id === chat.id }"
          @click="batchMode ? toggleChatSelection(chat) : switchChat(chat)"
        >
          <div v-if="batchMode" class="mr-2">
            <el-checkbox 
              v-model="chat.selected" 
              @click.stop 
              @change="updateSelectedChats"
            />
              </div>
          <el-icon class="mr-2 text-gray-400 group-hover:text-primary-500">
            <ChatLineRound />
          </el-icon>
          <div v-if="chat.isEditing" class="flex-1 mr-2" @click.stop>
            <el-input 
              v-model="chat.editTitle" 
              size="small"
              @blur="saveTitle(chat)"
              @keyup.enter="saveTitle(chat)"
              ref="titleInput"
              autofocus
            />
            </div>
          <div v-else class="flex-1 truncate text-sm">{{ chat.title }}</div>
          <div class="flex">
            <el-button
              v-if="!batchMode"
              type="text"
              class="opacity-0 group-hover:opacity-100 transition-opacity !text-gray-400 hover:!text-blue-500"
              @click.stop="startRenameChat(chat)"
            >
              <el-icon><Edit /></el-icon>
            </el-button>
            <el-popconfirm
              v-if="!batchMode"
              title="确定要删除这个对话吗？"
              confirm-button-text="删除"
              cancel-button-text="取消"
              @confirm="deleteChat(chat.id)"
            >
              <template #reference>
                <el-button
                  type="text"
                  class="opacity-0 group-hover:opacity-100 transition-opacity !text-gray-400 hover:!text-red-500"
                  @click.stop
                >
                  <el-icon><Delete /></el-icon>
                </el-button>
              </template>
            </el-popconfirm>
                </div>
                </div>
              </div>

      <!-- 底部提示 -->
      <div class="p-4 border-t border-gray-200 shrink-0">
        <div class="text-xs text-gray-500 space-y-1">
          <div class="flex items-center">
            <el-icon class="mr-1"><InfoFilled /></el-icon>
            <span>AI助手专注于贵港旅游咨询</span>
                </div>
          <div class="flex items-center">
            <el-icon class="mr-1"><Warning /></el-icon>
            <span>请勿透露个人敏感信息</span>
              </div>
            </div>
          </div>
        </div>

    <!-- 主聊天区域 -->
    <div
      class="flex-1 flex flex-col bg-gray-50 dark:bg-gray-900 overflow-hidden"
      @paste="handlePaste"
      @drop.prevent="handleDrop"
      @dragover.prevent
    >
      <!-- 模型选择 -->
      <div
        class="bg-white dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 p-4 flex justify-between items-center"
      >
        <div class="flex items-center space-x-4">
          <el-popover
            placement="bottom-start"
            :width="300"
            trigger="click"
            popper-class="model-selector-popover dark:bg-gray-800 dark:border-gray-700"
          >
            <template #reference>
              <div
                class="flex items-center space-x-2 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700 p-2 rounded-md w-fit"
              >
                <span class="text-sm font-medium dark:text-gray-200">{{
                  selectedModel.name
                }}</span>
                <el-icon class="dark:text-gray-400"><ArrowDown /></el-icon>
              </div>
            </template>

            <div class="p-2">
              <div class="mb-4">
                <div class="text-sm font-medium mb-2 dark:text-gray-200">
                  选择模型
            </div>
                <div class="text-xs text-gray-500 dark:text-gray-400">
                  选择不同的AI模型来回答您的问题
              </div>
            </div>
              <div class="space-y-2">
                <div
                  v-for="model in availableModels"
                  :key="model.id"
                  class="model-option flex items-center p-3 rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-700"
                  :class="{
                    'bg-gray-50 dark:bg-gray-700':
                      selectedModel.id === model.id,
                  }"
                  @click="selectModel(model)"
                >
                  <div class="flex-1">
                    <div class="text-sm font-medium dark:text-gray-200">
                      {{ model.name }}
              </div>
                    <div class="text-xs text-gray-500 dark:text-gray-400">
                      {{ model.description }}
            </div>
          </div>
                <el-icon
                    v-if="selectedModel.id === model.id"
                    class="text-primary-500"
                    ><Check
                /></el-icon>
        </div>
      </div>
    </div>
          </el-popover>

          <!-- 登录提示 -->
          <div v-if="!isLoggedIn" class="flex items-center">
            <el-tag type="warning">未登录</el-tag>
                </div>
                </div>

        <div class="flex items-center space-x-2">
          <!-- 思考过程显示开关 -->
          <el-tooltip content="显示/隐藏AI思考过程" placement="bottom">
            <el-switch
              v-model="showAiReasoning"
              inactive-text="思考过程"
              class="mr-2"
              size="small"
            />
          </el-tooltip>
          
          <el-tooltip content="导出聊天记录" placement="bottom">
            <el-button
              class="hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-200 transition-colors"
              @click="exportAllChats"
              :disabled="!chatHistory.length"
            >
              <el-icon><Download /></el-icon>
            </el-button>
          </el-tooltip>

          <el-tooltip content="帮助指南" placement="bottom">
            <el-button
              class="hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-200 transition-colors"
              @click="showHelpGuide"
            >
              <el-icon><QuestionFilled /></el-icon>
            </el-button>
          </el-tooltip>
                  </div>
                </div>

      <!-- 聊天消息列表 -->
      <div
        ref="messageContainer"
        class="flex-1 overflow-y-auto p-4 space-y-4 custom-scrollbar"
      >
        <template v-if="currentChat">
          <template v-if="currentChat.messages.length === 0">
            <!-- 欢迎界面 -->
            <div class="max-w-4xl mx-auto">
              <div class="text-center mb-8">
                <h2 class="text-2xl font-bold mb-2">
                  欢迎使用贵港旅游 AI 助手
                </h2>
                <p class="text-gray-600">
                  我是您的专属旅游顾问，让我为您规划完美的贵港之旅
                </p>
                </div>

              <div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-8">
                <div class="feature-card bg-white p-4 rounded-lg shadow-sm">
                  <div class="text-primary-500 mb-2">
                    <el-icon :size="24"><Location /></el-icon>
              </div>
                  <h3 class="text-lg font-medium mb-2">景点推荐</h3>
                  <p class="text-gray-600 text-sm">
                    为您推荐最适合的景点，提供详细的游玩攻略和注意事项
                  </p>
          </div>
                <div class="feature-card bg-white p-4 rounded-lg shadow-sm">
                  <div class="text-primary-500 mb-2">
                    <el-icon :size="24"><Food /></el-icon>
                </div>
                  <h3 class="text-lg font-medium mb-2">美食指南</h3>
                  <p class="text-gray-600 text-sm">
                    发现地道美食，了解特色小吃，寻找网红打卡地
                  </p>
              </div>
                <div class="feature-card bg-white p-4 rounded-lg shadow-sm">
                  <div class="text-primary-500 mb-2">
                    <el-icon :size="24"><Van /></el-icon>
            </div>
                  <h3 class="text-lg font-medium mb-2">交通出行</h3>
                  <p class="text-gray-600 text-sm">
                    提供交通路线规划，帮您合理安排行程时间
                  </p>
          </div>
                <div class="feature-card bg-white p-4 rounded-lg shadow-sm">
                  <div class="text-primary-500 mb-2">
                    <el-icon :size="24"><Calendar /></el-icon>
        </div>
                  <h3 class="text-lg font-medium mb-2">行程定制</h3>
                  <p class="text-gray-600 text-sm">
                    根据您的偏好和时间，定制专属旅游行程
                  </p>
          </div>
          </div>

              <div
                class="bg-white rounded-lg shadow-sm p-6 dark:bg-gray-800 dark:border dark:border-gray-700"
              >
                <h3 class="text-lg font-medium mb-4 dark:text-gray-200">
                  您可以这样问我
                </h3>
                <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
                  <div
                    v-for="(example, index) in exampleQuestions"
                    :key="index"
                    class="example-question p-3 rounded-lg bg-gray-50 hover:bg-gray-100 cursor-pointer transition-colors dark:bg-gray-700/50 dark:hover:bg-gray-700 dark:text-gray-300"
                    @click="useExampleQuestion(example)"
                  >
                    <div class="flex items-center text-sm">
                      <el-icon
                        class="mr-2 text-primary-500 dark:text-primary-400"
                        ><ChatLineRound
        /></el-icon>
                      {{ example }}
        </div>
      </div>
                </div>
                </div>
              </div>
            </template>
            <template v-else>
            <div
              v-for="message in currentChat.messages"
              :key="message.id"
              class="message-item flex group relative mb-6"
              :class="{ 'justify-end': message.role === 'user' }"
            >
              <!-- 助手头像和信息 -->
              <div v-if="message.role === 'assistant'" class="flex-shrink-0 mr-3 mt-1">
              <el-avatar
                :size="40"
                  :src="aiAvatar"
                  class="flex-shrink-0 border-2 border-white shadow-md"
                />
                </div>

              <div class="flex flex-col max-w-2xl relative">
                <!-- 用户名和时间 - 仅对助手消息显示在上方 -->
                <div v-if="message.role === 'assistant'" class="flex items-center justify-between mb-1">
                  <span class="text-sm font-medium">
                    贵港文旅+ AI助手
                  </span>
                  <div class="flex items-center">
                    <!-- 版本信息显示 -->
                    <span v-if="message.versions && message.versions.length > 1" class="text-xs bg-gray-100 text-gray-600 rounded px-2 py-0.5 mr-2">
                      第 {{ message.currentVersionIndex + 1 }} 版 / 共 {{ message.versions.length }} 版
                    </span>
                    
                    <!-- 如果是正在流式传输的消息，显示动画指示器和停止按钮 -->
                    <div
                      v-if="isStreaming && streamingMessageId === message.id"
                      class="flex items-center mr-2"
                    >
                      <span class="loading-dots mr-2"></span>
                      <el-button
                        type="text"
                        size="small"
                        class="text-xs !text-gray-500 hover:!text-gray-700 dark:hover:!text-gray-300"
                        @click="finishStreaming"
                      >
                        停止生成
                      </el-button>
                    </div>
                    <span class="text-xs text-gray-500">
                      {{ formatTime(message.id) }}
                    </span>
                  </div>
                </div>
                
                <!-- 思考过程内容 - 移到消息头部和消息气泡之间 -->
                <div
                  v-if="showAiReasoning && message.role === 'assistant' && message.versions && message.versions[message.currentVersionIndex] && message.versions[message.currentVersionIndex].hasReasoning && message.versions[message.currentVersionIndex].reasoningContent && !message.versions[message.currentVersionIndex].hideReasoning"
                  class="reasoning-content mb-3 p-3 bg-gray-100 dark:bg-gray-700 rounded-md text-sm opacity-70"
                >
                  <div class="text-xs mb-1 text-gray-500 dark:text-gray-400 flex justify-between">
                    <span>AI思考过程：</span>
                    <div class="flex space-x-2">
                      <button @click="message.versions[message.currentVersionIndex].hideReasoning = true" class="text-xs text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">
                        <i class="el-icon-close"></i>隐藏
                      </button>
                    </div>
                  </div>
                  <div class="whitespace-pre-wrap">{{ message.versions[message.currentVersionIndex].reasoningContent }}</div>
                </div>

                <!-- 消息气泡 -->
                <div
                  class="message-content rounded-lg p-3 relative"
                  :class="[
                    message.role === 'user'
                      ? (message.isEditing ? 'bg-white shadow-sm border border-primary-300' : 'bg-primary-500 text-white')
                      : 'bg-white shadow-sm',
                  ]"
                >
                  <!-- 用户消息编辑模式 -->
                  <div v-if="message.role === 'user' && message.isEditing" class="user-message-edit">
                    <el-input
                      v-model="message.editContent"
                      type="textarea"
                      :rows="3"
                      placeholder="编辑您的消息..."
                      resize="none"
                      autofocus
                    />
                    <div class="flex justify-end mt-2 space-x-2">
                      <el-button size="small" @click="cancelEditMessage(message)">取消</el-button>
                      <el-button size="small" type="primary" @click="saveEditedMessage(message)">发送</el-button>
                    </div>
                  </div>
                  
                  <!-- 非编辑模式下的用户消息内容 -->
                  <div v-else-if="message.role === 'user'" class="message-text text-sm whitespace-pre-wrap">
                    {{ message.versions && message.versions[message.currentVersionIndex] 
                        ? message.versions[message.currentVersionIndex].content 
                        : message.content }}
                  </div>
                  
                  <!-- 非用户消息内容 -->
                  <div v-else class="message-text text-sm">
                    <!-- 思考中状态 -->
                    <div 
                      v-if="message.versions && message.versions[message.currentVersionIndex] && message.versions[message.currentVersionIndex].isThinking" 
                      class="py-2"
                    >
                      <ThinkingIndicator />
                    </div>
                    <!-- 从这里删除思考过程内容，因为已移至上方 -->
                    <!-- Markdown内容 -->
                    <template v-else>
                      <MarkdownRenderer
                        v-if="shouldUseMarkdown(message.versions && message.versions[message.currentVersionIndex] ? message.versions[message.currentVersionIndex].content : message.content)"
                        :content="
                          message.versions && message.versions[message.currentVersionIndex]
                            ? (isStreaming && streamingMessageId === message.id
                                ? filterDebugText(fixRepeatedCharacters(message.versions[message.currentVersionIndex].content)) + (message.versions[message.currentVersionIndex].showCursor ? '▌' : '')
                                : filterDebugText(fixRepeatedCharacters(message.versions[message.currentVersionIndex].content)))
                              : filterDebugText(fixRepeatedCharacters(message.content))
                        "
                        class="markdown-content"
                      />
                      <!-- 纯文本内容 -->
                      <div v-else class="whitespace-pre-wrap">
                        {{ message.versions && message.versions[message.currentVersionIndex] 
                          ? filterDebugText(fixRepeatedCharacters(message.versions[message.currentVersionIndex].content))
                          : filterDebugText(fixRepeatedCharacters(message.content)) }}
                        <!-- 纯文本的流式传输光标效果 -->
                        <span
                          v-if="
                            isStreaming && 
                            streamingMessageId === message.id &&
                            message.versions && message.versions[message.currentVersionIndex] && 
                            message.versions[message.currentVersionIndex].showCursor
                          "
                          class="animate-cursor"
                          >▌</span
                        >
                      </div>
                    </template>
                  </div>

                  <!-- 搜索结果显示 -->
                  <div 
                    v-if="message.role === 'assistant' && 
                         message.versions && 
                         message.versions[message.currentVersionIndex] && 
                         message.versions[message.currentVersionIndex].searchResults && 
                         message.versions[message.currentVersionIndex].searchResults.length > 0" 
                    class="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700"
                  >
                    <div class="flex items-center mb-2 text-sm text-gray-600 dark:text-gray-400">
                      <el-icon class="mr-1"><Search /></el-icon>
                      <span>搜索结果</span>
                    </div>
                    <div class="search-results grid grid-cols-1 gap-3">
                      <div 
                        v-for="(result, index) in message.versions[message.currentVersionIndex].searchResults" 
                        :key="index"
                        class="search-result-card bg-gray-50 dark:bg-gray-800/50 p-3 rounded-lg border border-gray-200 dark:border-gray-700"
                      >
                        <div class="flex items-start">
                          <div 
                            v-if="result.image" 
                            class="w-16 h-16 rounded overflow-hidden shrink-0 mr-3"
                          >
                            <img :src="result.image" class="w-full h-full object-cover" />
                          </div>
                          <div class="flex-1 min-w-0">
                            <h4 class="text-sm font-medium mb-1 text-primary-600 dark:text-primary-400">
                              <a :href="result.url" target="_blank" class="hover:underline">{{ result.title }}</a>
                            </h4>
                            <div class="text-xs text-gray-800 dark:text-gray-300 mb-1 truncate">
                              {{ result.url }}
                            </div>
                            <p class="text-xs text-gray-600 dark:text-gray-400 line-clamp-2">
                              {{ result.snippet }}
                            </p>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>

                <!-- 操作按钮 - 现在位于消息气泡外部的右下角 -->
                <div 
                  class="message-actions flex justify-end items-center space-x-1"
                  v-if="!isStreaming && !message.isEditing"
                >
                  <!-- 助手消息的按钮 -->
                  <template v-if="message.role === 'assistant'">
                    <!-- 版本切换按钮 -->
                    <template v-if="message.versions && message.versions.length > 1">
                      <el-tooltip content="上一个版本" placement="top">
                        <el-button
                          type="default"
                          circle
                          size="small"
                          class="!border-gray-200 dark:!border-gray-700 dark:!bg-gray-800"
                          @click="switchMessageVersion(message, 'prev')"
                          :disabled="message.currentVersionIndex === 0"
                        >
                          <el-icon><ArrowLeft /></el-icon>
                        </el-button>
                      </el-tooltip>
                      <el-tooltip content="下一个版本" placement="top">
                        <el-button
                          type="default"
                          circle
                          size="small"
                          class="!border-gray-200 dark:!border-gray-700 dark:!bg-gray-800"
                          @click="switchMessageVersion(message, 'next')"
                          :disabled="message.currentVersionIndex === message.versions.length - 1"
                        >
                          <el-icon><ArrowRight /></el-icon>
                        </el-button>
                      </el-tooltip>
                      <span class="text-xs text-gray-500 mx-1">第{{ message.currentVersionIndex + 1 }}版/共{{ message.versions.length }}版</span>
                    </template>
                    
                    <el-tooltip content="复制内容" placement="top">
                      <el-button
                        type="default"
                        circle
                        size="small"
                        class="!border-gray-200 dark:!border-gray-700 dark:!bg-gray-800"
                        @click="copyMessage(message)"
                      >
                        <el-icon><CopyDocument /></el-icon>
                      </el-button>
                    </el-tooltip>
                    <el-tooltip content="重新生成" placement="top">
                      <el-button
                        type="default"
                        circle
                        size="small"
                        class="!border-gray-200 dark:!border-gray-700 dark:!bg-gray-800"
                        @click="regenerateMessage(message)"
                        :disabled="isStreaming"
                      >
                        <el-icon><RefreshRight /></el-icon>
                      </el-button>
                    </el-tooltip>
                  </template>
                  
                  <!-- 用户消息的按钮 -->
                  <template v-else>
                    <!-- 添加用户消息版本切换按钮 -->
                    <template v-if="message.versions && message.versions.length > 1">
                      <el-tooltip content="上一个版本" placement="top">
                        <el-button
                          type="default"
                          circle
                          size="small"
                          class="!border-gray-200 dark:!border-gray-700 dark:!bg-gray-800"
                          @click="switchMessageVersion(message, 'prev')"
                          :disabled="message.currentVersionIndex === 0"
                        >
                          <el-icon><ArrowLeft /></el-icon>
                        </el-button>
                      </el-tooltip>
                      <el-tooltip content="下一个版本" placement="top">
                        <el-button
                          type="default"
                          circle
                          size="small"
                          class="!border-gray-200 dark:!border-gray-700 dark:!bg-gray-800"
                          @click="switchMessageVersion(message, 'next')"
                          :disabled="message.currentVersionIndex === message.versions.length - 1"
                        >
                          <el-icon><ArrowRight /></el-icon>
                        </el-button>
                      </el-tooltip>
                      <span class="text-xs text-gray-500 mx-1">第{{ message.currentVersionIndex + 1 }}版/共{{ message.versions.length }}版</span>
                    </template>
                    
                    <!-- 编辑消息按钮（已注释掉） -->
                    <!--
                    <el-tooltip content="编辑消息" placement="top">
                      <el-button
                        type="primary"
                        circle
                        size="small"
                        class="!bg-primary-500 !border-primary-300"
                        @click="editUserMessage(message)"
                      >
                        <el-icon><Edit /></el-icon>
                      </el-button>
                    </el-tooltip>
                    -->
                  </template>
                </div>
                
                <!-- 用户消息的时间显示在下方右侧 -->
                <div v-if="message.role === 'user'" class="flex justify-end mt-1">
                  <span class="text-xs text-gray-500">{{ formatTime(message.id) }}</span>
                </div>
              </div>
              
              <!-- 用户头像 -->
              <div v-if="message.role === 'user'" class="flex-shrink-0 ml-3 mt-1">
                <el-avatar
                  :size="40"
                  :src="userAvatar"
                  class="flex-shrink-0 border-2 border-white shadow-md"
                />
              </div>
            </div>
          </template>
        </template>
        <div
          v-else
          class="h-full flex items-center justify-center text-gray-400"
        >
          <div class="text-center">
            <el-icon :size="40" class="mb-3"><ChatLineRound /></el-icon>
            <div class="text-sm">开始一个新的对话吧</div>
            <div class="mt-2 text-xs text-gray-500">
              AI助手将为您推荐贵港最佳旅游体验
                  </div>
                </div>
              </div>
            </div>

      <!-- 输入区域 -->
      <div
        class="shrink-0 p-4 bg-white dark:bg-gray-800 border-t border-gray-200 dark:border-gray-700"
      >
        <div
          class="max-w-4xl mx-auto relative"
          @paste="handlePaste"
          @drop.prevent="handleDrop"
          @dragover.prevent
        >
          <!-- 工具栏 -->
          <div class="flex items-center space-x-3 mb-2">
            <div class="flex items-center space-x-1">
              <el-tooltip content="上传图片" placement="top">
              <el-upload
                  action="#"
                  :auto-upload="false"
                :show-file-list="false"
                  accept="image/*"
                  :on-change="handleImageSelect"
                >
                  <el-button
                    class="tool-button"
                    :class="[
                      selectedImages.length > 0 ? 'is-active' : '',
                      'dark:!bg-blue-500/10 dark:hover:!bg-blue-500/20 dark:!text-blue-400',
                    ]"
                  >
                  <el-icon><Picture /></el-icon>
                  </el-button>
              </el-upload>
            </el-tooltip>

              <el-tooltip content="上传文件" placement="top">
              <el-upload
                  action="#"
                  :auto-upload="false"
                :show-file-list="false"
                  :on-change="handleFileSelect"
                >
                  <el-button
                    class="tool-button"
                    :class="[
                      selectedFiles.length > 0 ? 'is-active' : '',
                      'dark:!bg-green-500/10 dark:hover:!bg-green-500/20 dark:!text-green-400',
                    ]"
                  >
                  <el-icon><Upload /></el-icon>
                  </el-button>
              </el-upload>
            </el-tooltip>

              <el-tooltip content="联网搜索" placement="top">
                <el-button
                  class="tool-button"
                  :class="[
                    isSearchEnabled ? 'is-active' : '',
                    'dark:!bg-purple-500/10 dark:hover:!bg-purple-500/20 dark:!text-purple-400',
                  ]"
                  @click="toggleSearch"
                >
                  <el-icon><Search /></el-icon>
                </el-button>
            </el-tooltip>
            
            <el-tooltip content="提示词库" placement="top">
              <el-button
                class="tool-button"
                :class="[
                  showPromptLibrary ? 'is-active' : '',
                  'dark:!bg-yellow-500/10 dark:hover:!bg-yellow-500/20 dark:!text-yellow-400',
                ]"
                @click="togglePromptLibrary"
              >
                <el-icon><ChatLineRound /></el-icon>
              </el-button>
            </el-tooltip>
          </div>

            <div class="flex-1"></div>

            <div class="flex items-center space-x-2">
              <el-button
                type="text"
                size="small"
                class="!text-gray-500 hover:!text-gray-700"
                @click="clearChat"
                :disabled="!currentChat?.messages.length"
              >
                <el-icon class="mr-1"><Delete /></el-icon>
                清空对话
              </el-button>
              <el-button
                type="text"
                size="small"
                class="!text-gray-500 hover:!text-gray-700"
                @click="exportChat"
                :disabled="!currentChat?.messages.length"
              >
                <el-icon class="mr-1"><Download /></el-icon>
                导出对话
              </el-button>
                </div>
          </div>

          <!-- 预览区域 -->
          <div
            v-if="selectedFiles.length || selectedImages.length"
            class="mb-2"
              >
                <div class="flex flex-wrap gap-2">
              <!-- 图片预览 -->
              <div
                v-for="(image, index) in selectedImages"
                :key="'img-' + index"
                class="relative group"
              >
                <el-image
                  :src="image.url"
                  fit="cover"
                  class="w-16 h-16 rounded object-cover dark:border dark:border-gray-700"
                />
                <div
                  class="absolute top-1 right-1 opacity-0 group-hover:opacity-100 transition-opacity"
                >
                <el-button
                    type="danger"
                    circle
                    size="small"
                    class="dark:!bg-red-500/20 dark:hover:!bg-red-500/30"
                    @click="selectedImages.splice(index, 1)"
                  >
                    <el-icon><Close /></el-icon>
                </el-button>
              </div>
            </div>
              <!-- 文件预览 -->
              <div
                v-for="(file, index) in selectedFiles"
                :key="'file-' + index"
                class="flex items-center p-2 bg-gray-50 dark:bg-gray-800 rounded group dark:border dark:border-gray-700"
              >
                <el-icon class="mr-2 dark:text-gray-400"><Document /></el-icon>
                <span class="text-xs truncate dark:text-gray-300">{{
                  file.name
                }}</span>
                <el-button
                  type="danger"
                  link
                  size="small"
                  class="ml-2 dark:!text-red-400"
                  @click="selectedFiles.splice(index, 1)"
                >
                  <el-icon><Close /></el-icon>
                </el-button>
            </div>
          </div>
        </div>

          <!-- 提示词库组件 -->
          <div v-if="showPromptLibrary" class="mb-2 bg-white dark:bg-gray-800 p-3 rounded-lg border border-gray-200 dark:border-gray-700 shadow-sm">
            <div class="flex justify-between items-center mb-2">
              <h3 class="text-sm font-medium dark:text-gray-200">常用提示词</h3>
              <el-button 
                type="text" 
                class="!text-gray-500 hover:!text-gray-700 dark:text-gray-400"
                @click="showPromptLibrary = false"
              >
                <el-icon><Close /></el-icon>
              </el-button>
      </div>

            <div class="space-y-2">
              <div class="flex flex-wrap gap-2">
                <el-tag 
                  v-for="(category, index) in promptCategories" 
                  :key="index"
                  :class="{'!bg-primary-500 !text-white': selectedPromptCategory === index}"
                  class="cursor-pointer !border-none"
                  @click="selectedPromptCategory = index"
                >
                  {{ category.name }}
                </el-tag>
      </div>
              
              <div class="grid grid-cols-2 md:grid-cols-3 gap-2 mt-2">
                <div 
                  v-for="(prompt, index) in currentCategoryPrompts" 
                  :key="index"
                  class="p-2 text-xs bg-gray-50 dark:bg-gray-700 rounded cursor-pointer hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors"
                  @click="usePrompt(prompt)"
                >
                  {{ prompt.title }}
                </div>
              </div>
            </div>
          </div>

          <!-- 输入框 -->
            <div class="flex space-x-2">
          <el-input
              v-model="inputMessage"
            type="textarea"
                :rows="3"
              :maxlength="1000"
              show-word-limit
              placeholder="请输入您想咨询的贵港旅游相关问题..."
                resize="none"
              @keydown="handleKeyDown"
              class="flex-1"
              :disabled="isStreaming"
            />
                <el-button
              v-if="isStreaming"
              type="warning"
              class="!h-full w-24"
              @click="finishStreaming"
            >
              <span>停止</span>
              <span class="block text-xs opacity-80 mt-1">生成</span>
            </el-button>
            <el-button
              v-else
                  type="primary"
              class="!h-full w-24 !bg-gradient-to-r from-primary-500 to-primary-600"
              :disabled="!canSend"
              @click="sendMessage"
            >
              <el-icon v-if="sending" class="animate-spin"><Loading /></el-icon>
              <template v-else>
                <span>发送</span>
                <span class="block text-xs opacity-80 mt-1">(Enter)</span>
            </template>
                </el-button>
              </div>
          <div
            class="mt-2 flex justify-between items-center text-xs text-gray-500"
          >
            <div>
              <template v-if="isStreaming">
                <span class="text-primary-500">AI正在生成回答...</span>
      </template>
              <template v-else>
                提示：按 Enter 发送消息，Shift + Enter 换行
              </template>
            </div>
            <div>
              {{
                selectedFiles.length || selectedImages.length
                  ? "已选择 " +
                    (selectedFiles.length + selectedImages.length) +
                    " 个文件"
                  : ""
              }}
            </div>
          </div>
        </div>
      </div>
      </div>
  </div>
</template>

<script setup>
import { ref, computed, nextTick, onMounted, watch } from "vue";
import { useRouter } from "vue-router";
import {
  ChatLineRound,
  Plus,
  Delete,
  Loading,
  Back,
  InfoFilled,
  Warning,
  Download,
  Picture,
  Upload,
  Document,
  Close,
  ArrowDown,
  Check,
  Search,
  Location,
  Food,
  Van,
  Calendar,
  QuestionFilled,
  RefreshRight,
  CopyDocument,
  Edit,
  ArrowLeft,
  ArrowRight,
} from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import dayjs from "dayjs";
import Breadcrumb from "@/components/global/Breadcrumb.vue";
import { useUserStore } from "@/stores/user";
import MarkdownRenderer from "@/components/global/MarkdownRenderer.vue";
import ThinkingIndicator from "@/components/global/ThinkingIndicator.vue";
import { analyzeMessageContent } from "@/utils/messageFormatUtils";
import service, { createSSEConnection, noTimeoutService } from "@/api/axios"; // 引入axios服务和SSE连接函数

const router = useRouter();
const userStore = useUserStore();

// 用户头像和AI头像
const userAvatar = computed(
  () => userStore.avatar || "/images/avatars/default-avatar.png",
);
const aiAvatar = "/images/avatars/ai-avatar.png";

// 可用的AI模型
const availableModels = ref([
  {
    id: "deepseek-v3",
    name: "Deepseek V3",
    description: "专注于中文旅游领域的AI模型，提供准确的本地化服务",
  },
  {
    id: "deepseek-r1",
    name: "Deepseek R1",
    description: "适合复杂的旅游规划和深度文化解析",
  },
  {
    id: "gpt-4",
    name: "GPT-4",
    description: "强大的通用AI模型，支持多语言交互",
  },
  {
    id: "qianwen",
    name: "通义千问",
    description: "阿里云智能助手，擅长中文语境理解",
  },
]);

// 当前选择的模型
const selectedModel = ref(
  availableModels.value.find((model) => model.id === "deepseek-v3"),
);

// 选择模型
const selectModel = (model) => {
  selectedModel.value = model;
};

// 聊天历史
const chatHistory = ref([]);
const currentChat = ref(null);
const inputMessage = ref("");
const sending = ref(false);
const messageContainer = ref(null);

// 历史对话搜索与批量管理
const searchQuery = ref('');
const batchMode = ref(false);
const selectedChats = ref([]);

// 过滤后的聊天历史
const filteredChatHistory = computed(() => {
  if (!searchQuery.value.trim()) return chatHistory.value;
  
  const query = searchQuery.value.toLowerCase();
  return chatHistory.value.filter((chat) => {
    return chat.title.toLowerCase().includes(query) || 
      chat.messages.some(msg => msg.content.toLowerCase().includes(query));
  });
});

// 切换批量管理模式
const toggleBatchMode = () => {
  if (!batchMode.value) {
    // 退出批量模式时清空选择
    selectedChats.value = [];
    chatHistory.value.forEach(chat => {
      chat.selected = false;
    });
  }
};

// 全选/取消全选
const selectAll = () => {
  const allSelected = filteredChatHistory.value.every(chat => chat.selected);
  filteredChatHistory.value.forEach(chat => {
    chat.selected = !allSelected;
  });
  updateSelectedChats();
};

// 切换单个对话选择状态
const toggleChatSelection = (chat) => {
  chat.selected = !chat.selected;
  updateSelectedChats();
};

// 批量删除对话
const batchDeleteChats = async () => {
  if (!selectedChats.value.length) return;
  
  try {
    await ElMessageBox.confirm(
      `确定要删除选中的 ${selectedChats.value.length} 个对话吗？此操作不可恢复。`,
      "警告",
      {
        confirmButtonText: "删除",
        cancelButtonText: "取消",
        type: "warning",
      }
    );
    
    // 记录当前对话ID
    const currentChatId = currentChat.value?.id;
    
    // 获取服务器数据和本地数据
    const serverChats = selectedChats.value.filter(chat => chat.isFromServer);
    
    // 如果有服务器数据且用户已登录，批量删除服务器数据
    if (serverChats.length > 0 && isLoggedIn.value) {
      try {
        const ids = serverChats.map(chat => chat.id);
        console.log('📡 API调用: 批量删除对话', { ids });
        await service.post('/ai-chat/conversations/batch-delete', {
          ids: ids
        });
        console.log('✅ API响应: 批量删除对话成功');
      } catch (error) {
        console.error("❌ API错误: 批量删除服务器对话失败:", error);
      }
    }
    
    // 删除选中的对话
    selectedChats.value.forEach(chat => {
      const index = chatHistory.value.findIndex(c => c.id === chat.id);
      if (index > -1) {
        chatHistory.value.splice(index, 1);
      }
    });
    
    // 如果当前对话被删除，切换到第一个对话
    if (currentChatId && !chatHistory.value.find(c => c.id === currentChatId)) {
      currentChat.value = chatHistory.value[0] || null;
    }
    
    // 清空选中的对话
    selectedChats.value = [];
    // 退出批量模式
    batchMode.value = false;
    
    ElMessage.success(`已删除 ${selectedChats.value.length} 个对话`);
  } catch (e) {
    // 用户取消操作
    console.log('ℹ️ 用户取消了批量删除操作');
  }
};

// 选中的文件
const selectedFiles = ref([]);
const selectedImages = ref([]);

// 联网搜索状态
const isSearchEnabled = ref(false);

// 添加提示词库相关状态
const showPromptLibrary = ref(false);
const selectedPromptCategory = ref(0);

// 提示词分类
const promptCategories = ref([
  {
    name: "景点咨询",
    prompts: [
      { 
        title: "推荐景点", 
        content: "请为我推荐贵港市有哪些值得一去的景点，并简要介绍它们的特色和门票信息。" 
      },
      { 
        title: "最佳旅游季节", 
        content: "贵港什么季节最适合旅游？各个季节有什么特色景观？" 
      },
      { 
        title: "一日游路线", 
        content: "请规划一条贵港一日游的最佳路线，包括景点、餐饮和交通安排。" 
      },
      { 
        title: "亲子游景点", 
        content: "贵港有哪些适合带孩子游玩的景点？有什么特别的亲子活动？" 
      },
      { 
        title: "摄影打卡点", 
        content: "我想在贵港拍摄美丽的照片，请推荐几个最佳的摄影打卡地点和最佳拍摄时间。" 
      },
      { 
        title: "自然风光", 
        content: "贵港有哪些自然风光值得游览？如何前往这些地方？" 
      }
    ]
  },
  {
    name: "美食探索",
    prompts: [
      { 
        title: "特色小吃", 
        content: "贵港有哪些必吃的特色小吃？在哪里可以品尝到最正宗的？" 
      },
      { 
        title: "餐厅推荐", 
        content: "请推荐几家贵港评价较高的餐厅，包括他们的招牌菜和价格范围。" 
      },
      { 
        title: "美食街推荐", 
        content: "贵港有哪些美食街或夜市？它们各有什么特色？" 
      },
      { 
        title: "当地特产", 
        content: "贵港有哪些值得带走的食品特产或手信？在哪里可以购买？" 
      },
      { 
        title: "素食选择", 
        content: "作为素食者，在贵港有哪些好的餐厅或食物选择？" 
      }
    ]
  },
  {
    name: "交通出行",
    prompts: [
      { 
        title: "到达方式", 
        content: "从广州/南宁如何到达贵港？有哪些交通方式可选？" 
      },
      { 
        title: "市内交通", 
        content: "贵港市内有哪些公共交通方式？如何使用及费用如何？" 
      },
      { 
        title: "租车信息", 
        content: "在贵港租车需要什么条件？有哪些租车公司推荐？" 
      },
      { 
        title: "景点之间交通", 
        content: "贵港主要景点之间如何换乘？有什么便捷的方式？" 
      }
    ]
  },
  {
    name: "住宿选择",
    prompts: [
      { 
        title: "酒店推荐", 
        content: "请推荐几家贵港性价比高的酒店，最好靠近主要景区。" 
      },
      { 
        title: "特色民宿", 
        content: "贵港有什么特色民宿值得体验？价格如何？" 
      },
      { 
        title: "经济住宿", 
        content: "贵港有哪些干净舒适又经济实惠的住宿选择？" 
      }
    ]
  },
  {
    name: "文化历史",
    prompts: [
      { 
        title: "历史背景", 
        content: "贵港的历史渊源是什么？有哪些重要的历史事件？" 
      },
      { 
        title: "文化特色", 
        content: "贵港有什么独特的地方文化和风俗习惯？" 
      },
      { 
        title: "节日活动", 
        content: "贵港有哪些特色节日或文化活动？在什么时间举行？" 
      }
    ]
  }
]);

// 当前选中分类的提示词
const currentCategoryPrompts = computed(() => {
  return promptCategories.value[selectedPromptCategory.value].prompts;
});

// 使用提示词
const usePrompt = (prompt) => {
  inputMessage.value = prompt.content;
  showPromptLibrary.value = false;
};

// 切换联网搜索
const toggleSearch = () => {
  isSearchEnabled.value = !isSearchEnabled.value;
  ElMessage.success(
    isSearchEnabled.value ? "已开启联网搜索" : "已关闭联网搜索",
  );
};

// 切换提示词库显示
const togglePromptLibrary = () => {
  showPromptLibrary.value = !showPromptLibrary.value;
};

// 是否可以发送消息
const canSend = computed(() => {
  return (
    (inputMessage.value.trim() ||
      selectedFiles.value.length ||
      selectedImages.value.length) &&
    !sending.value &&
    !isStreaming.value
  );
});

// 处理图片选择
const handleImageSelect = (file) => {
  if (!file) return;

  // 检查文件大小（限制为5MB）
  if (file.size > 5 * 1024 * 1024) {
    ElMessage.warning("图片大小不能超过5MB");
    return;
  }

  // 创建预览URL
  const url = URL.createObjectURL(file.raw);
  selectedImages.value.push({
    file: file.raw,
    url,
  });
};

// 处理文件选择
const handleFileSelect = (file) => {
  if (!file) return;

  // 检查文件大小（限制为10MB）
  if (file.size > 10 * 1024 * 1024) {
    ElMessage.warning("文件大小不能超过10MB");
    return;
  }

  selectedFiles.value.push(file.raw);
};

// 下载文件
const downloadFile = (file) => {
  const link = document.createElement("a");
  link.href = file.url;
  link.download = file.name;
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

// 移除图片
const removeImage = (message, index) => {
  message.images.splice(index, 1);
};

// 移除文件
const removeFile = (message, index) => {
  message.files.splice(index, 1);
};

// 当前用户的临时会话ID
const tempSessionId = ref(null);

// 获取或创建临时会话ID（针对未登录用户）
const getOrCreateTempSession = async () => {
  if (isLoggedIn.value) return null; // 已登录用户不需要临时会话
  
  if (tempSessionId.value) {
    console.log('ℹ️ 使用已有临时会话ID:', tempSessionId.value);
    // 这里只返回会话ID，不创建新对话
    return tempSessionId.value;
  }
  
  try {
    console.log('📡 API调用: 创建临时会话');
    // 1. 先创建临时会话获取sessionId
    const sessionRes = await noTimeoutService.post('/public/ai-chat/session');
    console.log('✅ API响应: 创建临时会话', sessionRes.data);
    
    if (sessionRes.data && sessionRes.data.sessionId) {
      tempSessionId.value = sessionRes.data.sessionId;
      // 保存到localStorage，以便重新打开页面时可以继续使用
      localStorage.setItem('tempAiChatSessionId', tempSessionId.value);
      
      return tempSessionId.value;
    }
    throw new Error('未获取到有效的sessionId');
  } catch (error) {
    console.error('❌ API错误: 创建临时会话失败:', error);
    // 创建自己的临时ID作为备用
    tempSessionId.value = `temp-${Date.now()}`;
    localStorage.setItem('tempAiChatSessionId', tempSessionId.value);
    return tempSessionId.value;
  }
};

// 为未登录用户创建对话并获取conversationId
const createTempConversation = async (sessionId) => {
  // 根据后端API设计，未登录用户不支持创建对话
  // 我们直接返回会话ID作为标识
  console.log('ℹ️ 未登录用户不支持创建对话，直接使用会话ID');
  return sessionId;
};

// 创建新对话
const createNewChat = async () => {
  try {
    if (isLoggedIn.value) {
      // 已登录用户使用正常API
      console.log('📡 API调用: 已登录用户创建新对话');
      const res = await noTimeoutService.post('/ai-chat/conversations');
      console.log('✅ API响应: 创建新对话', res.data);
      const newChat = {
        id: res.data.id,
        title: res.data.title,
        messages: [],
        isFromServer: true, // 标记为服务器数据
      };
      chatHistory.value.unshift(newChat);
      switchChat(newChat);
    } else {
      // 未登录用户创建本地对话，但会通过公共API发送消息
      console.log('ℹ️ 未登录用户创建本地对话');
      // 获取临时会话ID
      const sessionId = await getOrCreateTempSession();
      if (!sessionId) {
        throw new Error('获取临时会话ID失败');
      }
      
      // 未登录用户直接使用sessionId，不创建conversationId
      const newChat = {
        id: Date.now(), // 本地唯一ID
        title: "新对话",
        messages: [],
        isFromServer: false, // 标记为本地数据
        sessionId: sessionId // 保存sessionId用于后续API调用
      };
      chatHistory.value.unshift(newChat);
      switchChat(newChat);
    }
  } catch (error) {
    console.error("❌ API错误: 创建对话失败:", error);
    // 创建失败时使用本地测试数据
    const newChat = {
      id: Date.now(),
      title: "新对话",
      messages: [],
      isFromServer: false, // 标记为本地数据
    };
    chatHistory.value.unshift(newChat);
    switchChat(newChat);
  }
};

// 切换对话
const switchChat = async (chat) => {
  console.log(`🔄 切换到对话: ID=${chat.id}, 标题=${chat.title}`);
  currentChat.value = chat;
  
  // 如果是服务器数据且消息为空，则加载消息
  if (chat.isFromServer && (!chat.messages || chat.messages.length === 0)) {
    try {
      console.log(`🔍 开始加载对话消息: ID=${chat.id}`);
      const messages = await loadConversationMessages(chat.id);
      chat.messages = messages;
      console.log(`📑 对话消息加载完成: ID=${chat.id}, 消息数量=${messages.length}`);
    } catch (error) {
      console.error(`❌ 加载对话消息失败: ID=${chat.id}`, error);
      chat.messages = [];
    }
  }
  
  scrollToBottom();
};

// 删除对话
const deleteChat = async (chatId) => {
  try {
    const chat = chatHistory.value.find(c => c.id === chatId);
    
    if (chat && chat.isFromServer) {
      // 如果是服务器数据，调用API删除
      console.log(`📡 API调用: 删除对话, 对话ID=${chatId}`);
      await service.delete(`/ai-chat/conversations/${chatId}`);
      console.log(`✅ API响应: 删除对话成功, 对话ID=${chatId}`);
    } else {
      console.log(`ℹ️ 本地操作: 删除本地对话, 对话ID=${chatId}`);
    }
    
    // 无论是否为服务器数据，都从本地移除
    const index = chatHistory.value.findIndex((chat) => chat.id === chatId);
    if (index > -1) {
      chatHistory.value.splice(index, 1);
      if (currentChat.value?.id === chatId) {
        currentChat.value = chatHistory.value[0] || null;
      }
    }
  } catch (error) {
    console.error(`❌ API错误: 删除对话失败, 对话ID=${chatId}:`, error);
    ElMessage.error("删除对话失败，请重试");
  }
};

// 清空当前对话
const clearChat = async () => {
  try {
    await ElMessageBox.confirm(
      "确定要清空当前对话吗？此操作不可恢复。",
      "提示",
      {
        confirmButtonText: "清空",
        cancelButtonText: "取消",
        type: "warning",
      },
    );
    
    if (currentChat.value) {
      // 服务器数据清空
      if (currentChat.value.isFromServer) {
        try {
          console.log(`📡 API调用: 清空对话消息, 对话ID=${currentChat.value.id}`);
          await service.delete(`/ai-chat/conversations/${currentChat.value.id}/messages`);
          console.log(`✅ API响应: 清空对话消息成功, 对话ID=${currentChat.value.id}`);
        } catch (error) {
          console.error(`❌ API错误: 清空对话消息失败, 对话ID=${currentChat.value.id}:`, error);
        }
      } else {
        console.log(`ℹ️ 本地操作: 清空本地对话消息, 对话ID=${currentChat.value.id}`);
      }
      
      // 本地数据清空
      currentChat.value.messages = [];
      currentChat.value.title = "新对话";
    }
  } catch (e) {
    // 用户取消操作
    console.log('ℹ️ 用户取消了清空对话操作');
  }
};

// 导出对话
const exportChat = async () => {
  if (!currentChat.value?.messages.length) return;

  try {
    // 如果是服务器数据，调用服务器导出API
    if (currentChat.value.isFromServer) {
      try {
        // 尝试使用服务器导出功能
        console.log(`📡 API调用: 导出对话, 对话ID=${currentChat.value.id}`);
        const res = await service.get(`/ai-chat/conversations/${currentChat.value.id}/export`, {
          responseType: 'blob'
        });
        console.log(`✅ API响应: 导出对话成功, 对话ID=${currentChat.value.id}`, { size: res.data.size });
        
        // 创建下载链接
        const url = URL.createObjectURL(new Blob([res.data]));
        const link = document.createElement("a");
        link.href = url;
        link.download = `对话记录_${dayjs().format("YYYY-MM-DD_HH-mm-ss")}.txt`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
        return;
      } catch (error) {
        console.error(`❌ API错误: 服务器导出失败, 对话ID=${currentChat.value.id}:`, error);
      }
    }
    
    console.log('ℹ️ 本地操作: 使用本地导出');
    // 本地导出逻辑
    const chatContent = currentChat.value.messages
      .map((msg) => {
        const role = msg.role === "user" ? "我" : "贵港文旅+ AI助手";
        const time = formatTime(msg.id);
        // 使用版本控制中的内容
        const content = msg.versions && msg.versions[msg.currentVersionIndex] 
          ? msg.versions[msg.currentVersionIndex].content 
          : msg.content;
        return `${role} (${time}):\n${content}\n`;
      })
      .join("\n");

    const blob = new Blob([chatContent], { type: "text/plain;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = `对话记录_${dayjs().format("YYYY-MM-DD_HH-mm-ss")}.txt`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  } catch (error) {
    console.error("❌ 错误: 导出对话失败:", error);
    ElMessage.error("导出对话失败，请重试");
  }
};

// 处理回车键
const handleKeyDown = (e) => {
  if (e.key === "Enter") {
    if (isStreaming.value) {
      // 如果正在流式传输，Enter可以停止生成
      e.preventDefault();
      finishStreaming();
      return;
    }

    if (e.shiftKey) {
      // Shift + Enter 换行
      inputMessage.value += "\n";
    } else {
      // 普通Enter发送消息
      e.preventDefault();
      sendMessage();
    }
  } else if (e.key === "Escape" && isStreaming.value) {
    // Escape键也可以取消流式传输
    finishStreaming();
  }
};

// 格式化时间
const formatTime = (timestamp) => {
  return dayjs(timestamp).format("HH:mm:ss");
};

// 发送消息
const sendMessage = async () => {
  if (!canSend.value || isStreaming.value) return;

  // 如果当前正在流式传输，取消它
  if (isStreaming.value) {
    finishStreaming();
  }

  if (!currentChat.value) {
    await createNewChat();
  }

  console.log('🚀 开始发送消息');
  
  // 准备用户消息数据
  const userMessageId = Date.now();
  const userMessage = {
    id: userMessageId,
    role: "user",
    content: inputMessage.value.trim(),
    images: [],
    files: [],
    isEditing: false,
    editContent: "",
    versions: [
      {
        id: Date.now(),
        content: inputMessage.value.trim(),
        timestamp: Date.now()
      }
    ],
    currentVersionIndex: 0
  };

  // 处理图片上传
  if (selectedImages.value.length) {
    // 模拟上传成功
    userMessage.images = selectedImages.value.map((img) => img.url);
    console.log(`📷 添加了${selectedImages.value.length}张图片`);
  }

  // 处理文件上传
  if (selectedFiles.value.length) {
    // 模拟上传成功
    userMessage.files = selectedFiles.value.map((file) => ({
      name: file.name,
      url: URL.createObjectURL(file),
      size: file.size,
    }));
    console.log(`📎 添加了${selectedFiles.value.length}个文件`);
  }

  // 添加到本地消息列表
  currentChat.value.messages.push(userMessage);

  // 如果是第一条消息，更新对话标题
  if (currentChat.value.messages.length === 1) {
    currentChat.value.title = userMessage.content.slice(0, 20) + (userMessage.content.length > 20 ? "..." : "");
    
    // 如果是服务器数据，更新服务器上的标题
    if (currentChat.value.isFromServer) {
      try {
        console.log(`📡 API调用: 更新对话标题, 对话ID=${currentChat.value.id}`, {
          title: currentChat.value.title
        });
        await service.put(`/ai-chat/conversations/${currentChat.value.id}`, {
          title: currentChat.value.title
        });
        console.log(`✅ API响应: 更新对话标题成功, 对话ID=${currentChat.value.id}`);
      } catch (error) {
        console.error(`❌ API错误: 更新对话标题失败, 对话ID=${currentChat.value.id}:`, error);
      }
    }
  }

  // 清空输入和选中的文件
  inputMessage.value = "";
  selectedFiles.value = [];
  selectedImages.value = [];

  await scrollToBottom();

  try {
    sending.value = true;

    // 创建一个空的助手消息
    const assistantMessageId = Date.now();
    const assistantMessage = {
      id: assistantMessageId,
      role: "assistant",
      content: "",
      isStreaming: true,
      versions: [{ 
        id: Date.now(),
        content: "",
        isThinking: true,
        showCursor: false,
        searchResults: [],
      }],
      currentVersionIndex: 0,
    };

    currentChat.value.messages.push(assistantMessage);
    await scrollToBottom();

    // 准备流式请求所需的参数
    const requestData = {
      content: userMessage.content,
      modelId: selectedModel.value.id
    };

    // 添加conversationId (如果有)
    if (isLoggedIn.value && currentChat.value.isFromServer) {
      requestData.conversationId = currentChat.value.id;
    }

    // 添加附件数据 (如果有)
    const attachments = [];
    if (userMessage.images.length) {
      attachments.push(...userMessage.images.map(url => ({
        type: 'image',
        url
      })));
    }
    if (userMessage.files.length) {
      attachments.push(...userMessage.files.map(file => ({
        type: 'file',
        url: file.url,
        name: file.name,
        size: file.size
      })));
    }
    if (attachments.length) {
      requestData.attachments = attachments;
    }

    console.log('📡 API调用: 使用流式接口发送消息', requestData);

    // 直接使用流式接口
    if (isLoggedIn.value && currentChat.value.isFromServer) {
      // 已登录用户使用正常API
      receiveStreamResponse(assistantMessageId, requestData, true);
    } else if (currentChat.value.sessionId) {
      // 未登录用户使用公共API
      receiveStreamResponse(assistantMessageId, requestData, false, currentChat.value.sessionId);
    } else {
      console.log('ℹ️ 使用本地数据: 非服务器对话且无会话ID，使用模拟回复');
      // 尝试创建临时会话并再次发送
      try {
        const sessionId = await getOrCreateTempSession();
        if (sessionId) {
          // 更新当前对话的sessionId
          currentChat.value.sessionId = sessionId;
          // 再次使用流式接口发送
          receiveStreamResponse(assistantMessageId, requestData, false, sessionId);
        } else {
          // 无法创建会话，使用模拟回复
          useFallbackResponse(userMessage.content, assistantMessageId);
        }
      } catch (error) {
        console.error("❌ API错误: 创建会话并发送消息失败:", error);
        // 调用失败时使用模拟回复
        useFallbackResponse(userMessage.content, assistantMessageId);
      }
    }
  } catch (error) {
    console.error('❌ 错误: 发送消息失败', error);
    ElMessage.error("发送消息失败，请重试");
    // 出错时清除正在流式传输的消息
    if (isStreaming.value) {
      finishStreaming();
    }
  } finally {
    sending.value = false;
  }
};

// 处理服务器响应
const handleServerResponse = (response, messageId) => {
  // 模拟API调用延迟
  setTimeout(() => {
    simulateStreamingResponse(response, messageId);
  }, 300);
};

// 使用备用响应（测试数据）
const useFallbackResponse = (userContent, messageId) => {
  // 移除旅游相关问题检查
  // 使用流式传输显示消息
  if (isSearchEnabled.value) {
    performWebSearch(userContent, messageId);
  } else {
    // 模拟API延迟
    setTimeout(() => {
      const suggestions = [
        "这是一个关于您询问的问题的回答。我是一个AI助手，可以帮助回答各种问题，包括但不限于贵港旅游相关的内容。您可以询问我任何您感兴趣的话题。",
        "感谢您的提问。我可以回答多种类型的问题，无论是关于贵港旅游、历史文化、科学技术还是日常生活的问题，我都会尽力为您提供有用的信息。",
        "我是贵港文旅+的AI助手，不仅可以回答关于贵港旅游的问题，也能够提供其他方面的知识和帮助。如果您有任何问题，都可以随时向我提问。",
        "收到您的问题了。我能够处理各种类型的查询，包括但不限于旅游建议、知识问答、信息查找等。请随时告诉我您需要了解的内容。",
        "我很乐意回答您的问题。作为AI助手，我可以处理多种类型的问题，并尽力提供准确、有用的信息。如果有任何其他问题，请继续向我提问。",
      ];

      // 随机选择一个更详细的回答
      const response = suggestions[Math.floor(Math.random() * suggestions.length)];

      // 使用流式传输显示消息
      simulateStreamingResponse(response, messageId);
    }, 300);
  }
};

// 执行网页搜索
const performWebSearch = async (query, messageId) => {
  try {
    // 模拟网络请求延迟
    await new Promise(resolve => setTimeout(resolve, 2000));
    
    // 模拟搜索结果
    const searchResults = generateMockSearchResults(query);
    
    // 将搜索结果添加到消息中
    const message = currentChat.value.messages.find(
      (msg) => msg.id === messageId
    );
    
    if (message) {
      const currentVersion = message.versions[message.currentVersionIndex];
      currentVersion.searchResults = searchResults;
      currentVersion.isThinking = false;
      
      // 基于搜索结果生成回复
      const generatedResponse = generateResponseFromSearchResults(searchResults, query);
      
      // 使用流式传输显示基于搜索结果的回复
      simulateStreamingResponse(generatedResponse, messageId);
    }
  } catch (error) {
    console.error('搜索失败:', error);
    
    // 如果搜索失败，回退到普通回复
    const suggestions = [
      "根据我的信息，贵港是一座美丽的城市，拥有众多特色景点。您可以游览贵港园博园、江滨公园等知名景点，感受城市的自然风光和人文魅力。",
      "我了解到，贵港的美食非常丰富，推荐您尝试贵港粉、荷叶粉、艾糍粑等特色小吃。春季和秋季是品尝这些美食的最佳时节，尤其是在当地的夜市和小吃街，您可以找到最正宗的贵港美食。",
    ];
    
    const response = "抱歉，搜索服务暂时不可用。\n\n" + 
                     suggestions[Math.floor(Math.random() * suggestions.length)];
    
    simulateStreamingResponse(response, messageId);
  }
};

// 生成模拟搜索结果
const generateMockSearchResults = (query) => {
  // 根据不同的查询关键词生成不同的搜索结果
  const searchResults = [];
  
  // 保留原有的旅游相关搜索结果生成逻辑
  if (query.includes('景点') || query.includes('游玩') || query.includes('旅游')) {
    searchResults.push(
      {
        title: "贵港园博园 - 广西壮族自治区著名景点",
        url: "https://travel.example.com/guigang-garden-expo",
        snippet: "贵港园博园位于贵港市港北区，占地面积约1200亩，是广西壮族自治区重点文化旅游项目。园内设有12个特色园区，集中展示了中国传统园林艺术和岭南建筑特色...",
        image: "https://via.placeholder.com/160x120?text=园博园"
      },
      {
        title: "贵港旅游攻略 - 必去景点推荐",
        url: "https://www.mafengwo.cn/example/guigang",
        snippet: "贵港的江滨公园沿西江而建，是贵港的城市名片。公园内绿树成荫，景色宜人，是当地居民休闲和游客观赏西江风光的好去处。公园还设有多个特色景点和娱乐设施...",
        image: "https://via.placeholder.com/160x120?text=江滨公园"
      },
      {
        title: "2023贵港旅游必去5大景点 - 游客点评",
        url: "https://www.dianping.com/example/guigang-attractions",
        snippet: "观音山公园位于贵港市区东北部，因山上有观音寺而得名。登上山顶可以俯瞰整个贵港市区和西江水域，视野开阔，景色优美。山上的观音寺历史悠久，是信徒祈福的场所..."
      }
    );
  }
  
  if (query.includes('美食') || query.includes('吃') || query.includes('小吃')) {
    searchResults.push(
      {
        title: "贵港十大必吃美食 - 地道小吃攻略",
        url: "https://food.example.com/guigang-food",
        snippet: "贵港粉是贵港市最有名的特色小吃，选用上等大米磨制而成，细滑爽口。配以特制的卤水、酸笋、花生油、辣椒等调料，香气扑鼻，滋味鲜美...",
        image: "https://via.placeholder.com/160x120?text=贵港粉"
      },
      {
        title: "贵港美食街推荐 - 本地人带你吃遍贵港",
        url: "https://www.xiaohongshu.com/example/guigang-food-street",
        snippet: "荷叶粉是贵港的传统特色小吃，以糯米为主料，以荷叶包裹蒸熟。吃时撒上白糖或蘸酱油，香气四溢，软糯可口。每年端午节前后是品尝荷叶粉的最佳时节...",
        image: "https://via.placeholder.com/160x120?text=荷叶粉"
      }
    );
  }
  
  if (query.includes('住宿') || query.includes('酒店') || query.includes('住')) {
    searchResults.push(
      {
        title: "贵港市区十大高评分酒店 - 携程旅行",
        url: "https://hotels.example.com/guigang-hotels",
        snippet: "贵港华悦酒店位于市中心商圈，距离主要景点仅10分钟车程。酒店设施完善，拥有舒适的客房和专业的服务团队。酒店餐厅提供地道的贵港美食...",
        image: "https://via.placeholder.com/160x120?text=华悦酒店"
      },
      {
        title: "贵港特色民宿推荐 - 超高性价比住宿选择",
        url: "https://www.airbnb.com/example/guigang-homestay",
        snippet: "西江风情民宿位于江滨路，客房可直接观赏西江美景。民宿由当地艺术家设计，融合了贵港传统元素和现代艺术风格。每间客房都有不同的主题装饰，给游客带来独特的住宿体验..."
      }
    );
  }
  
  if (query.includes('交通') || query.includes('怎么去') || query.includes('路线')) {
    searchResults.push(
      {
        title: "贵港市内交通指南 - 自助游攻略",
        url: "https://travel.example.com/guigang-transportation",
        snippet: "贵港市区面积不大，市内主要交通方式有公交车和出租车。公交线路覆盖主要景点和商业区，票价1-2元。出租车起步价7元，市区内一般不超过20元...",
        image: "https://via.placeholder.com/160x120?text=贵港交通"
      },
      {
        title: "从南宁/广州到贵港的交通方式详解",
        url: "https://www.mafengwo.cn/example/to-guigang",
        snippet: "从广州到贵港，可以选择高铁、动车或长途汽车。高铁约需2.5小时，票价约150-200元；长途汽车需时约4小时，票价约120元..."
      }
    );
  }
  
  // 为非旅游问题添加通用搜索结果
  if (searchResults.length === 0) {
    searchResults.push(
      {
        title: "搜索结果 - " + query,
        url: "https://search.example.com/?q=" + encodeURIComponent(query),
        snippet: "这是关于您查询的「" + query + "」的搜索结果。AI助手可以回答各种问题，不仅限于旅游相关内容。",
        image: "https://via.placeholder.com/160x120?text=搜索结果"
      },
      {
        title: "智能问答 - 知识库",
        url: "https://kb.example.com/",
        snippet: "AI助手可以回答多种问题，包括但不限于旅游、科技、历史、生活等方面的内容，为用户提供全方位的信息服务。"
      }
    );
  }
  
  return searchResults;
};

// 基于搜索结果生成回复
const generateResponseFromSearchResults = (searchResults, query) => {
  // 提取搜索结果中的关键信息
  let extractedInfo = searchResults.map(result => {
    // 从标题和摘要中提取关键信息
    return result.snippet.split('。')[0] + '。';
  }).join('\n\n');
  
  // 根据查询内容和提取的信息生成不同类型的响应
  let intro = "根据网络搜索结果，我为您整理了以下信息：\n\n";
  
  // 保留原有的旅游相关回复生成逻辑
  if (query.includes('景点') || query.includes('游玩') || query.includes('旅游')) {
    intro = "根据网络搜索，贵港有以下值得一游的景点：\n\n";
  } else if (query.includes('美食') || query.includes('吃') || query.includes('小吃')) {
    intro = "根据网络搜索，贵港的特色美食有：\n\n";
  } else if (query.includes('住宿') || query.includes('酒店') || query.includes('住')) {
    intro = "根据网络搜索，贵港的住宿选择有：\n\n";
  } else if (query.includes('交通') || query.includes('怎么去') || query.includes('路线')) {
    intro = "根据网络搜索，关于贵港的交通信息如下：\n\n";
  }
  
  // 添加个性化建议
  let suggestion = "\n\n基于以上信息，";
  
  if (query.includes('景点') || query.includes('游玩') || query.includes('旅游')) {
    suggestion += "我建议您可以将贵港园博园和江滨公园作为必游景点，它们是贵港的标志性景点。如果时间充足，还可以考虑登上观音山俯瞰城市全景。建议预留一整天的时间游览这些景点，上午可以先游览园博园，下午游览江滨公园和观音山。";
  } else if (query.includes('美食') || query.includes('吃') || query.includes('小吃')) {
    suggestion += "我建议您一定要尝试贵港粉和荷叶粉这两种地道小吃。贵港粉最好在当地的早餐店或小吃店品尝，荷叶粉则在端午节前后品尝最为应景。贵港的夜市也是品尝各种地方小吃的好去处。";
  } else if (query.includes('住宿') || query.includes('酒店') || query.includes('住')) {
    suggestion += "我建议如果您注重便利性，可以选择市中心的酒店，交通便利且距离主要景点较近；如果追求特色体验，可以考虑江边的民宿，能够欣赏到西江美景。建议提前预订，特别是在旅游旺季。";
  } else if (query.includes('交通') || query.includes('怎么去') || query.includes('路线')) {
    suggestion += "我建议在市区内优先选择公交车出行，经济实惠且覆盖主要景点；如果行程紧凑或是晚上出行，可以选择出租车。如果从外地到贵港，高铁是最便捷的交通方式。";
  } else {
    suggestion += "希望上述信息对您有所帮助。如果您需要了解更多详细内容，或有其他问题，请继续向我提问。";
  }
  
  return intro + extractedInfo + suggestion;
};

// 滚动到底部
const scrollToBottom = async () => {
  await nextTick();
  if (messageContainer.value) {
    messageContainer.value.scrollTop = messageContainer.value.scrollHeight;
  }
};

// 示例问题
const exampleQuestions = ref([
  "贵港有哪些必去的景点？",
  "推荐几个贵港特色小吃",
  "从火车站到园博园怎么走？",
  "三天两晚的贵港旅游行程怎么安排？",
  "贵港现在天气怎么样？适合游玩吗？",
  "贵港有什么地方适合带孩子玩？",
  "贵港有什么特产推荐？",
  "住宿的话有什么好的酒店推荐？",
]);

// 使用示例问题
const useExampleQuestion = (question) => {
  inputMessage.value = question;
};

// 添加处理粘贴事件的函数
const handlePaste = (e) => {
  const items = e.clipboardData.items;
  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    if (item.type.indexOf("image") !== -1) {
      const file = item.getAsFile();
      handleImageSelect({ raw: file });
    } else if (item.kind === "file") {
      const file = item.getAsFile();
      handleFileSelect({ raw: file });
    }
  }
};

// 添加处理拖拽事件的函数
const handleDrop = (e) => {
  const files = e.dataTransfer.files;
  for (let i = 0; i < files.length; i++) {
    const file = files[i];
    if (file.type.startsWith("image/")) {
      handleImageSelect({ raw: file });
    } else {
      handleFileSelect({ raw: file });
    }
  }
};

// 检查登录状态
const isLoggedIn = computed(() => userStore.isLoggedIn);

// 初始化
onMounted(async () => {
  console.log('💻 AI聊天页面初始化');
  console.log('🔒 登录状态:', isLoggedIn.value ? '已登录' : '未登录');
  
  // 尝试从localStorage获取临时会话ID
  if (!isLoggedIn.value) {
    const savedSessionId = localStorage.getItem('tempAiChatSessionId');
    if (savedSessionId) {
      console.log('ℹ️ 从本地存储加载临时会话ID:', savedSessionId);
      tempSessionId.value = savedSessionId;
    } else {
      // 尝试创建新的临时会话
      await getOrCreateTempSession();
    }
  }
  
  // 检查登录状态并提示
  if (!isLoggedIn.value) {
    ElMessage({
      message:
        "您当前未登录，聊天记录将保存在当前浏览器会话中。登录后可以同步聊天记录。",
      type: "warning",
      duration: 5000,
      showClose: true,
    });
  }
  
  if (isLoggedIn.value) {
    // 已登录用户从服务器加载历史对话
    console.log('📡 尝试从服务器加载历史对话');
    await loadConversations();
    console.log('📦 服务器历史对话数量:', chatHistory.value.length);
  } else {
    // 未登录用户加载本地存储历史对话
    const savedHistory = localStorage.getItem("chatHistory");
    if (savedHistory) {
      try {
        console.log('ℹ️ 从本地存储加载历史对话');
        const parsedHistory = JSON.parse(savedHistory);
        
        // 确保每个对话都有sessionId
        chatHistory.value = parsedHistory.map(chat => {
          if (!chat.sessionId && tempSessionId.value) {
            chat.sessionId = tempSessionId.value;
          }
          return chat;
        });
        
        if (chatHistory.value.length > 0) {
          currentChat.value = chatHistory.value[0];
          // 不再尝试创建conversationId
        }
        console.log('📦 本地历史对话数量:', chatHistory.value.length);
      } catch (e) {
        console.error("❌ 错误: 加载本地历史对话失败:", e);
      }
    }
  }
  
  console.log('🌟 初始化完成');
});

// 监听聊天历史变化，仅在非服务器数据时保存到本地存储
watch(
  chatHistory,
  (newHistory) => {
    // 只有未登录或包含非服务器数据时才保存到本地
    if (!isLoggedIn.value || newHistory.some(chat => !chat.isFromServer)) {
      try {
        // 过滤出非服务器数据保存到本地
        const localChats = newHistory.filter(chat => !chat.isFromServer);
        localStorage.setItem("chatHistory", JSON.stringify(localChats));
      } catch (e) {
        console.error("Failed to save chat history:", e);
        ElMessage.warning("对话历史保存失败，请清理浏览器存储空间");
      }
    }
  },
  { deep: true },
);

// 清空所有对话
const clearAllChats = async () => {
  try {
    await ElMessageBox.confirm(
      "确定要清空所有对话记录吗？此操作不可恢复。",
      "警告",
      {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      },
    );
    
    // 服务器数据清空
    if (isLoggedIn.value) {
      try {
        await service.delete('/ai-chat/conversations');
      } catch (error) {
        console.error("清空所有对话失败:", error);
      }
    }
    
    // 本地数据清空
    chatHistory.value = [];
    currentChat.value = null;
    localStorage.removeItem("chatHistory");
    ElMessage.success("已清空所有对话记录");
  } catch (e) {
    // 用户取消操作
  }
};

// 导出所有聊天记录
const exportAllChats = async () => {
  if (!chatHistory.value.length) return;

  try {
    // 如果用户已登录且有服务器数据，尝试使用服务器导出
    if (isLoggedIn.value && chatHistory.value.some(chat => chat.isFromServer)) {
      try {
        // 尝试使用服务器导出功能
        const res = await service.get('/ai-chat/conversations/export-all', {
          responseType: 'blob'
        });
        
        // 创建下载链接
        const url = URL.createObjectURL(new Blob([res.data]));
        const link = document.createElement("a");
        link.href = url;
        link.download = `贵港旅游AI助手对话记录_${dayjs().format("YYYY-MM-DD_HH-mm-ss")}.txt`;
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(url);
        return;
      } catch (error) {
        console.error("服务器导出失败，使用本地导出:", error);
      }
    }
    
    // 本地导出逻辑
    const allChats = chatHistory.value
      .map((chat) => {
        const messages = chat.messages
          .map((msg) => {
            const role = msg.role === "user" ? "我" : "贵港文旅+ AI助手";
            const time = formatTime(msg.id);
            // 使用版本控制中的内容
            const content = msg.versions && msg.versions[msg.currentVersionIndex] 
              ? msg.versions[msg.currentVersionIndex].content 
              : msg.content;
            return `${role} (${time}):\n${content}\n`;
          })
          .join("\n");
        return `===== ${chat.title} =====\n\n${messages}\n\n`;
      })
      .join("----------------------------------------\n\n");

    const blob = new Blob([allChats], { type: "text/plain;charset=utf-8" });
    const url = URL.createObjectURL(blob);
    const link = document.createElement("a");
    link.href = url;
    link.download = `贵港旅游AI助手对话记录_${dayjs().format("YYYY-MM-DD_HH-mm-ss")}.txt`;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  } catch (error) {
    console.error("导出所有对话失败:", error);
    ElMessage.error("导出对话失败，请重试");
  }
};

// 显示帮助指南
const showHelpGuide = () => {
  ElMessageBox.alert(
    `<div class="space-y-4">
      <div>
        <h3 class="font-medium mb-2">🎯 功能介绍</h3>
        <p>• 贵港文旅+ AI助手专注于贵港旅游咨询服务</p>
        <p>• 支持景点推荐、美食指南、交通出行、行程定制等功能</p>
      </div>
      <div>
        <h3 class="font-medium mb-2">💡 使用技巧</h3>
        <p>• 可以通过选择不同的AI模型获得更专业的回答</p>
        <p>• 支持发送图片和文件，方便交流和分享</p>
        <p>• 使用示例问题快速开始对话</p>
      </div>
      <div>
        <h3 class="font-medium mb-2">⚠️ 注意事项</h3>
        <p>• 请勿透露个人敏感信息</p>
        <p>• 建议保存重要的对话内容</p>
        <p>• 如遇问题可以尝试刷新页面</p>
      </div>
    </div>`,
    "使用帮助",
    {
      confirmButtonText: "知道了",
      dangerouslyUseHTMLString: true,
      customClass: "help-guide-dialog",
    },
  );
};

// 添加流式传输相关变量和状态
const isStreaming = ref(false);
const streamingMessageId = ref(null);
const abortController = ref(null);
const streamingTimeout = ref(null);
const thinkingTimeout = ref(null);
const cursorBlinkInterval = ref(null);
const sseConnection = ref(null); // 添加SSE连接引用

// 模拟流式响应效果的函数
const simulateStreamingResponse = (response, messageId) => {
  isStreaming.value = true;
  streamingMessageId.value = messageId;

  const message = currentChat.value.messages.find(
    (msg) => msg.id === messageId,
  );
  if (!message) return;

  const currentVersion = message.versions[message.currentVersionIndex];

  // 思考状态一段时间
  thinkingTimeout.value = setTimeout(() => {
    currentVersion.isThinking = false;
    currentVersion.showCursor = true;
    // 启动光标闪烁
    startCursorBlink(currentVersion);

    // 如果用户询问的是关于代码、表格或Markdown的，返回带格式的响应
    if (currentChat.value.messages.length > 1) {
      const userMessage =
        currentChat.value.messages[currentChat.value.messages.length - 2];
      const userContent = userMessage.content.toLowerCase();

      if (
        userContent.includes("代码") ||
        userContent.includes("code") ||
        userContent.includes("编程") ||
        userContent.includes("program")
      ) {
        return simulateCodeResponse(messageId);
      }

      if (
        userContent.includes("表格") ||
        userContent.includes("table") ||
        userContent.includes("对比") ||
        userContent.includes("compare")
      ) {
        return simulateTableResponse(messageId);
      }

      if (
        userContent.includes("markdown") ||
        userContent.includes("格式化") ||
        userContent.includes("format")
      ) {
        return simulateMarkdownResponse(messageId);
      }
    }

    // 创建字符流
    const chars = response.split("");
    let currentIndex = 0;

    // 设置模拟字符流
    const streamChar = () => {
      if (currentIndex < chars.length) {
        // 追加字符到消息
        currentVersion.content += chars[currentIndex];
        currentIndex++;

        // 随机延迟，模拟真实打字效果
        const delay = getTypingDelay(chars[currentIndex - 1]);
        streamingTimeout.value = setTimeout(streamChar, delay);
      } else {
        // 流结束
        finishStreaming();
      }
    };

    // 开始流式响应
    streamChar();
  }, 1500); // 思考1.5秒
};

// 获取打字延迟时间，使打字效果更自然
const getTypingDelay = (char) => {
  // 标点符号后停顿更长
  if (['.', ',', '!', '?', ';', ':', '\n'].includes(char)) {
    return Math.floor(Math.random() * 300) + 100; // 100-400ms
  }
  
  // 空格后停顿稍长
  if (char === ' ') {
    return Math.floor(Math.random() * 40) + 30; // 30-70ms
  }
  
  // 普通字符
  return Math.floor(Math.random() * 15) + 10; // 10-25ms
};

// 启动光标闪烁效果
const startCursorBlink = (version) => {
  // 清除之前的闪烁计时器
  if (cursorBlinkInterval.value) {
    clearInterval(cursorBlinkInterval.value);
  }
  
  // 设置新的闪烁计时器
  cursorBlinkInterval.value = setInterval(() => {
    if (version && !version.isThinking) {
      version.showCursor = !version.showCursor;
    }
  }, 500); // 每500ms闪烁一次
};

// 结束流式响应
const finishStreaming = () => {
  const message = currentChat.value?.messages.find(
    (msg) => msg.id === streamingMessageId.value
  );
  
  if (message) {
    const currentVersion = message.versions[message.currentVersionIndex];
    // 结束思考状态
    currentVersion.isThinking = false;
    // 固定显示光标
    currentVersion.showCursor = false;
    
    // 同步版本内容到消息的主content字段（向后兼容）
    message.content = currentVersion.content;
  }
  
  isStreaming.value = false;
  streamingMessageId.value = null;
  
  if (streamingTimeout.value) {
    clearTimeout(streamingTimeout.value);
    streamingTimeout.value = null;
  }
  
  if (thinkingTimeout.value) {
    clearTimeout(thinkingTimeout.value);
    thinkingTimeout.value = null;
  }
  
  if (cursorBlinkInterval.value) {
    clearInterval(cursorBlinkInterval.value);
    cursorBlinkInterval.value = null;
  }
  
  if (abortController.value) {
    abortController.value = null;
  }
  
  // 关闭SSE连接
  if (sseConnection.value) {
    sseConnection.value.close();
    sseConnection.value = null;
  }
  
  // 最后再次滚动到底部，确保所有内容都显示出来
  setTimeout(() => {
    scrollToBottom();
  }, 100);
  
  // 如果用户已登录且对话来自服务器，保存聊天记录
  if (isLoggedIn.value && currentChat.value?.isFromServer) {
    console.log('保存聊天记录...');
    saveCurrentChat();
  }
};

// 模拟代码响应
const simulateCodeResponse = (messageId) => {
  const message = currentChat.value.messages.find(
    (msg) => msg.id === messageId,
  );
  if (!message) return;

  const codeResponse = `贵港景点信息查询系统可以使用以下Python代码实现：

\`\`\`python
import json
import requests

class GuigangTourismAPI:
    """贵港旅游景点信息查询API"""
    
    def __init__(self, api_key):
        self.api_key = api_key
        self.base_url = "https://api.guigang-tourism.cn/v1"
    
    def get_attractions(self, category=None, limit=10):
        """获取景点列表
        
        参数:
            category: 景点类别 (自然景观, 历史文化, 休闲娱乐)
            limit: 返回结果数量限制
        """
        endpoint = f"{self.base_url}/attractions"
        params = {
            "api_key": self.api_key,
            "limit": limit
        }
        
        if category:
            params["category"] = category
            
        response = requests.get(endpoint, params=params)
        
        if response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"API请求失败: {response.status_code}")
    
    def get_attraction_details(self, attraction_id):
        """获取景点详细信息
        
        参数:
            attraction_id: 景点ID
        """
        endpoint = f"{self.base_url}/attractions/{attraction_id}"
        params = {"api_key": self.api_key}
        
        response = requests.get(endpoint, params=params)
        
        if response.status_code == 200:
            return response.json()
        else:
            raise Exception(f"API请求失败: {response.status_code}")


# 使用示例
def main():
    # 初始化API客户端
    api = GuigangTourismAPI(api_key="your_api_key")
    
    # 获取所有自然景观类景点
    natural_attractions = api.get_attractions(category="自然景观", limit=5)
    print(f"贵港自然景观景点TOP5:")
    for i, attraction in enumerate(natural_attractions["data"], 1):
        print(f"{i}. {attraction['name']} - {attraction['brief']}")
    
    # 获取指定景点的详细信息
    if natural_attractions["data"]:
        first_attraction = natural_attractions["data"][0]
        details = api.get_attraction_details(first_attraction["id"])
        
        print(f"\\n{details['name']}详细信息:")
        print(f"地址: {details['address']}")
        print(f"开放时间: {details['opening_hours']}")
        print(f"门票: {details['ticket_price']}")
        print(f"简介: {details['description']}")

if __name__ == "__main__":
    main()
\`\`\`

这段代码创建了一个用于查询贵港旅游景点信息的API客户端，可以获取景点列表和景点详情。使用时需要替换成实际的API密钥。`;

  streamMessageContent(message, codeResponse);
};

// 模拟表格响应
const simulateTableResponse = (messageId) => {
  const message = currentChat.value.messages.find(
    (msg) => msg.id === messageId,
  );
  if (!message) return;

  const tableResponse = `以下是贵港主要景点的对比表格：

| 景点名称 | 类型 | 门票价格 | 开放时间 | 推荐指数 | 特色亮点 |
|---------|------|---------|---------|---------|---------|
| 贵港园博园 | 公园/自然景观 | 60元 | 8:00-18:00 | ⭐⭐⭐⭐⭐ | 占地面积大，园林景观精美，四季花卉不同 |
| 江滨公园 | 公园/休闲 | 免费 | 全天开放 | ⭐⭐⭐⭐ | 沿江风景优美，是市民休闲娱乐的好去处 |
| 贵港博物馆 | 博物馆/文化 | 免费 | 9:00-17:00(周一闭馆) | ⭐⭐⭐⭐ | 展示贵港历史文化，馆藏文物丰富 |
| 观音山公园 | 自然景观/宗教 | 30元 | 8:00-17:30 | ⭐⭐⭐⭐ | 山顶可俯瞰全城，寺庙历史悠久 |
| 石龙文化园 | 文化/历史 | 40元 | 8:30-17:00 | ⭐⭐⭐⭐ | 石刻艺术精湛，文化底蕴深厚 |
| 贵港美食街 | 美食/休闲 | 免费 | 10:00-22:00 | ⭐⭐⭐⭐⭐ | 汇集贵港特色美食，品种多样 |

## 推荐游览路线

根据不同的游览时间，您可以选择以下路线：

### 一日游推荐
上午：贵港博物馆 → 江滨公园
下午：贵港园博园
晚上：贵港美食街

### 二日游推荐
第一天：贵港博物馆 → 江滨公园 → 贵港美食街
第二天：观音山公园 → 石龙文化园 → 贵港园博园`;

  streamMessageContent(message, tableResponse);
};

// 模拟Markdown格式响应
const simulateMarkdownResponse = (messageId) => {
  const message = currentChat.value.messages.find(
    (msg) => msg.id === messageId,
  );
  if (!message) return;

  const markdownResponse = `# 贵港旅游攻略

## 贵港简介

贵港市是广西壮族自治区的一个地级市，位于广西东部，**桂江**和**西江**在此汇合，自古就是西江流域的重要水陆交通枢纽，素有"广西东大门"之称。

## 最佳旅游季节

贵港属亚热带季风气候，四季分明，年平均气温20°C左右。春秋两季是游览贵港的最佳时间，尤其是3-4月和9-11月，气候宜人，适合户外活动。

> 温馨提示：夏季贵港较为炎热，请做好防暑准备；雨季出行请携带雨具。

## 必游景点

### 1. 贵港园博园 🌷

![园博园](https://example.com/yuanboyuan.jpg)

园博园是贵港市的城市名片，园内汇集了中国各地的特色园林和花卉，四季景色各异。

* **门票信息**：60元/人
* **开放时间**：08:00-18:00
* **地址**：贵港市港北区

### 2. 江滨公园 🌊

江滨公园沿西江而建，是欣赏西江风光的绝佳去处，也是当地市民休闲的热门场所。

* **门票信息**：免费
* **开放时间**：全天
* **地址**：贵港市港北区江滨路

### 3. 观音山公园 ⛰️

观音山公园位于市区东北部，山上有古刹和观音像，登顶可俯瞰贵港全城风光。

* **门票信息**：30元/人
* **开放时间**：08:00-17:30
* **地址**：贵港市港北区观音山

## 贵港特色美食

贵港的美食种类繁多，以下是几种不容错过的特色小吃：

1. **贵港粉** - 贵港最有名的特色小吃，细滑爽口，汤鲜味美
2. **荷叶粉** - 用荷叶包裹糯米制成，清香可口
3. **艾糍粑** - 春节传统糕点，口感软糯，香甜可口
4. **姜埋奶** - 将老姜和牛奶混合加热制成，暖胃健康

## 行程规划

### 三天两晚经典行程

| 日期 | 上午 | 下午 | 晚上 |
|-----|-----|-----|-----|
| 第一天 | 贵港博物馆 | 江滨公园 | 品尝贵港粉 |
| 第二天 | 贵港园博园 | 园博园(续) | 美食街体验 |
| 第三天 | 观音山公园 | 石龙文化园 | 返程 |

## 交通指南

### 如何到达贵港

* **飞机**：最近的机场是南宁吴圩国际机场，距离贵港约150公里
* **火车**：贵港火车站有多趟列车通往广州、南宁等城市
* **汽车**：贵港汽车站有发往周边各城市的班车

### 市内交通

贵港市区不大，主要交通方式有：
- 公交车：覆盖主要景点，票价1-2元
- 出租车：起步价7元
- 共享单车：市区内随处可见，使用方便

## 住宿推荐

* **高档**：贵港华悦酒店、皇冠假日酒店
* **中档**：锦江之星、如家快捷酒店
* **经济**：贵港青年旅舍、7天连锁酒店

希望这份攻略对您的贵港之旅有所帮助！祝您旅途愉快！`;

  streamMessageContent(message, markdownResponse);
};

// 流式传输消息内容的通用函数
const streamMessageContent = (message, content) => {
  const chars = content.split("");
  let currentIndex = 0;

  // 设置模拟字符流
  const streamChar = () => {
    if (currentIndex < chars.length) {
      // 追加字符到消息
      message.content += chars[currentIndex];
      currentIndex++;

      // 随机延迟，模拟真实打字效果
      let delay;

      // 标点符号后稍微暂停一下
      if (
        [".", ",", "!", "?", ";", ":", "\n"].includes(chars[currentIndex - 1])
      ) {
        delay = Math.floor(Math.random() * 40) + 30; // 30-70ms
      } else {
        delay = Math.floor(Math.random() * 15) + 10; // 10-25ms
      }

      streamingTimeout.value = setTimeout(streamChar, delay);
    } else {
      // 流结束
      finishStreaming();
    }
  };

  // 开始流式响应
  streamChar();
};

// 判断是否应该使用Markdown渲染
const shouldUseMarkdown = (content) => {
  if (!content) return false;
  
  // 检查是否包含明显的Markdown标记
  const markdownPatterns = [
    /\*\*[\s\S]+?\*\*/,        // 粗体
    /\*[\s\S]+?\*/,            // 斜体
    /^#+\s.+$/m,               // 标题
    /`[\s\S]+?`/,              // 行内代码
    /```[\s\S]*?```/,          // 代码块
    /\[[\s\S]+?\]\([\s\S]+?\)/, // 链接
    /!\[[\s\S]*?\]\([\s\S]+?\)/, // 图片
    /^\s*[-*+]\s.+$/m,         // 无序列表
    /^\s*\d+\.\s.+$/m,         // 有序列表
    /^\s*>.+$/m,               // 引用
    /\|[\s\S]+?\|[\s\S]+?\|/,   // 表格
    /^-{3,}$/m,                // 水平线
    /^={3,}$/m                 // 另一种水平线
  ];
  
  // 更新检查逻辑，确保能识别出更复杂的Markdown
  
  // 1. 检查是否包含多行段落格式（如Day 1, Day 2等标题后跟内容）
  if (/\*\*Day \d+.*\*\*[\s\S]*?(?=\*\*Day|\Z)/i.test(content)) {
    return true;
  }
  
  // 2. 检查明显的分隔线与内容结构
  if (/---[\s\S]*?---/m.test(content)) {
    return true;
  }
  
  // 3. 检查包含多个列表项的内容
  if (content.split(/^\s*[-*+]\s/m).length > 2) {
    return true;
  }
  
  // 4. 检查emoji+标题组合的常见模式
  if (/[\u{1F300}-\u{1F6FF}]\s*[\w\s]+：/u.test(content)) {
    return true;
  }
  
  // 5. 检查行程类内容的特征
  if ((/Day\s*\d+[：:]/i.test(content) || /[上下]午[：:]/i.test(content)) && 
      /\*\*.*?\*\*/i.test(content)) {
    return true;
  }
  
  // 6. 检查包含多个加粗文本的内容
  const boldTextMatches = content.match(/\*\*[\s\S]+?\*\*/g);
  if (boldTextMatches && boldTextMatches.length >= 2) {
    return true;
  }
  
  // 原有的基本检查
  return markdownPatterns.some(pattern => pattern.test(content));
};

// 添加用于修复重复字符的函数
const fixRepeatedCharacters = (text) => {
  if (!text) return text;
  
  // 修复常见的重复模式，如"欢迎欢迎来到来到贵贵港港！！"
  // 1. 检测并修复连续重复的单字
  let result = text.replace(/([一-龥])\1+/g, '$1');
  
  // 2. 检测并修复连续重复的词组（2-4个字）
  for (let len = 4; len >= 2; len--) {
    const pattern = new RegExp(`([\u4e00-\u9fa5]{${len}})(\\1)+`, 'g');
    result = result.replace(pattern, '$1');
  }
  
  // 3. 修复重复的标点符号（保留两个连续的相同符号，如感叹号！！）
  result = result.replace(/([！？。，；：、\.!?,;:\s])\1{2,}/g, '$1$1');
  
  return result;
};

// 过滤掉调试信息
const filterDebugText = (text) => {
  if (!text) return text;
  
  // 过滤掉常见的调试信息
  const debugPatterns = [
    /正在连接AI服务.../,
    /正在思考.../,
    /正在生成回答.../,
    /连接已建立.../,
    /初始化中.../
  ];
  
  // 如果文本内容完全匹配某个调试模式，返回空字符串
  if (debugPatterns.some(pattern => pattern.test(text) && text.trim().length < 30)) {
    return '';
  }
  
  return text;
};

// 重新生成消息
const regenerateMessage = async (message) => {
  if (isStreaming.value || !currentChat.value) return;

  // 找到当前消息的索引
  const messageIndex = currentChat.value.messages.findIndex(
    (m) => m.id === message.id,
  );
  if (messageIndex === -1) return;

  // 如果当前消息是助手消息，找到它对应的用户消息
  if (message.role === "assistant" && messageIndex > 0) {
    // 创建一个新版本
    if (!message.versions) {
      // 如果没有版本数组，创建一个并将当前内容作为第一个版本
      message.versions = [{
        id: Date.now() - 1000, // 确保比新版本早
        content: message.content,
        isThinking: false,
        showCursor: false,
        searchResults: message.searchResults || []
      }];
      message.currentVersionIndex = 0;
    }
    
    // 添加新版本
    message.versions.push({
      id: Date.now(),
      content: "",
      isThinking: true,
      showCursor: false,
      searchResults: []
    });
    message.currentVersionIndex = message.versions.length - 1;
    
    // 检查是否需要删除后续消息
    if (messageIndex < currentChat.value.messages.length - 1) {
      // 先确认用户是否同意删除后续消息
      ElMessageBox.confirm(
        "切换消息版本将会创建此回答的新版本，是否继续？",
        "提示",
        {
          confirmButtonText: "继续",
          cancelButtonText: "取消",
          type: "warning",
        },
      )
        .then(() => {
          // 不再删除后续消息，只重新生成当前消息的新版本
          doRegenerateMessage(messageIndex - 1, messageIndex);
        })
        .catch(() => {
          // 用户取消操作，回滚新增的版本
          message.versions.pop();
          message.currentVersionIndex = message.versions.length - 1;
        });
    } else {
      // 如果是最后一条消息，直接重新生成
      doRegenerateMessage(messageIndex - 1, messageIndex);
    }
  }
};

// 执行重新生成
const doRegenerateMessage = async (userMessageIndex, assistantMessageIndex) => {
  try {
    sending.value = true;

    // 获取用户消息和助手消息
    const userMessage = currentChat.value.messages[userMessageIndex];
    const assistantMessage = currentChat.value.messages[assistantMessageIndex];
    
    // 标记消息为正在重新生成
    assistantMessage.isRegenerating = true;
    
    console.log(`🔄 开始重新生成消息: 用户消息ID=${userMessage.id}, 助手消息ID=${assistantMessage.id}`);
    
    // 准备流式请求所需的参数
    const requestData = {
      modelId: selectedModel.value.id,
      content: userMessage.content
    };
    
    // 添加conversationId (如果有)
    if (isLoggedIn.value && currentChat.value.isFromServer) {
      requestData.conversationId = currentChat.value.id;
    }
    
    console.log(`📡 API调用: 使用流式接口重新生成消息, 消息ID=${assistantMessage.id}`, requestData);
    
    // 直接使用流式接口
    if (isLoggedIn.value && currentChat.value.isFromServer) {
      // 已登录用户使用正常API
      receiveStreamResponse(assistantMessage.id, requestData, true);
    } else if (currentChat.value.sessionId) {
      // 未登录用户使用公共API
      receiveStreamResponse(assistantMessage.id, requestData, false, currentChat.value.sessionId);
    } else {
      // 本地数据使用模拟响应
      useFallbackResponse(userMessage.content, assistantMessage.id);
    }
  } catch (error) {
    console.error('❌ 错误: 重新生成失败', error);
    ElMessage.error("重新生成失败，请重试");
    // 出错时清除正在流式传输的消息
    if (isStreaming.value) {
      finishStreaming();
    }
  } finally {
    sending.value = false;
    // 重置重新生成标记
    if (currentChat.value) {
      const assistantMessage = currentChat.value.messages[assistantMessageIndex];
      if (assistantMessage) {
        assistantMessage.isRegenerating = false;
      }
    }
  }
};

// 复制消息内容
const copyMessage = (message) => {
  if (message.role === 'assistant' && message.versions && message.versions.length > 0) {
    navigator.clipboard.writeText(message.versions[message.currentVersionIndex].content);
  } else {
    navigator.clipboard.writeText(message.content);
  }
  ElMessage.success("内容已复制到剪贴板");
};

// 重命名对话
const startRenameChat = (chat) => {
  chat.isEditing = true;
  chat.editTitle = chat.title; 
  // 聚焦到输入框
  nextTick(() => {
    const inputEl = document.querySelector('.chat-item input');
    if (inputEl) inputEl.focus();
  });
};

// 保存对话标题
const saveTitle = (chat) => {
  chat.title = chat.editTitle || '新对话';
  chat.isEditing = false;
};

// 更新选中的对话
const updateSelectedChats = () => {
  selectedChats.value = chatHistory.value.filter(chat => chat.selected);
};

// 编辑用户消息
const editUserMessage = (message) => {
  // 将用户消息设置为编辑状态
  message.isEditing = true;
  message.editContent = message.versions && message.versions[message.currentVersionIndex]
    ? message.versions[message.currentVersionIndex].content
    : message.content;
  
  // 聚焦编辑区域
  nextTick(() => {
    const editArea = document.querySelector('.user-message-edit textarea');
    if (editArea) editArea.focus();
  });
};

const cancelEditMessage = (message) => {
  message.isEditing = false;
  message.editContent = message.content;
};

// 保存编辑后的用户消息
const saveEditedMessage = async (message) => {
  if (!message.editContent.trim()) {
    ElMessage.warning('消息内容不能为空');
    return;
  }
  
  // 找到当前消息的索引
  const messageIndex = currentChat.value.messages.findIndex((m) => m.id === message.id);
  if (messageIndex === -1) return;
  
  // 初始化版本控制相关属性
  if (!message.versions) {
    message.versions = [{
      content: message.content,
      timestamp: Date.now()
    }];
    message.currentVersionIndex = 0;
  }
  
  // 添加新版本
  message.versions.push({
    content: message.editContent.trim(),
    timestamp: Date.now()
  });
  message.currentVersionIndex = message.versions.length - 1;
  
  // 更新消息内容
  message.content = message.editContent.trim();
  message.isEditing = false;
  
  // 如果是第一条消息，更新对话标题
  if (messageIndex === 0) {
    currentChat.value.title =
      message.content.slice(0, 20) +
      (message.content.length > 20 ? "..." : "");
    
    // 如果是服务器数据，则更新服务器上的标题
    if (currentChat.value.isFromServer && isLoggedIn.value) {
      try {
        await service.put(`/ai-chat/conversations/${currentChat.value.id}`, {
          title: currentChat.value.title
        });
      } catch (error) {
        console.error("更新对话标题失败:", error);
      }
    }
  }
  
  // 生成编辑后的消息回复
  if (messageIndex < currentChat.value.messages.length - 1) {
    // 找到下一个助手消息（如果存在）
    const nextAssistantMessageIndex = currentChat.value.messages.findIndex((m, index) => 
      index > messageIndex && m.role === 'assistant'
    );
    
    if (nextAssistantMessageIndex !== -1) {
      // 获取助手消息
      const assistantMessage = currentChat.value.messages[nextAssistantMessageIndex];
      
      // 如果助手消息没有版本控制，初始化它
      if (!assistantMessage.versions) {
        assistantMessage.versions = [{
          content: assistantMessage.content,
          isThinking: false,
          timestamp: Date.now(),
          showCursor: false
        }];
        assistantMessage.currentVersionIndex = 0;
      }
      
      // 添加新版本
      assistantMessage.versions.push({
        content: '',
        isThinking: true,
        timestamp: Date.now(),
        showCursor: false
      });
      assistantMessage.currentVersionIndex = assistantMessage.versions.length - 1;
      
      // 滚动到底部
      nextTick(() => {
        scrollToBottom();
      });
      
      // 准备流式请求所需的参数
      const requestData = {
        modelId: selectedModel.value.id,
        content: message.content,
        userMessageId: message.id
      };
      
      // 添加conversationId (如果有)
      if (isLoggedIn.value && currentChat.value.isFromServer) {
        requestData.conversationId = currentChat.value.id;
      }
      
      console.log(`📡 API调用: 编辑消息后使用流式接口重新生成, 消息ID=${assistantMessage.id}`, requestData);
      
      // 标记消息为重新生成
      assistantMessage.isRegenerating = true;
      
      try {
        // 直接使用流式接口
        if (isLoggedIn.value && currentChat.value.isFromServer) {
          // 已登录用户使用正常API
          receiveStreamResponse(assistantMessage.id, requestData, true);
        } else if (currentChat.value.sessionId) {
          // 未登录用户使用公共API
          receiveStreamResponse(assistantMessage.id, requestData, false, currentChat.value.sessionId);
        } else {
          // 本地数据使用模拟响应
          useFallbackResponse(message.content, assistantMessage.id);
        }
      } catch (error) {
        console.error("重新生成消息失败:", error);
        // 失败时使用本地模拟回复
        useFallbackResponse(message.content, assistantMessage.id);
      } finally {
        // 重置重新生成标记
        assistantMessage.isRegenerating = false;
      }
    }
  }
};

const switchMessageVersion = (message, direction) => {
  if (!message || !message.versions || message.versions.length <= 1) return;
  
  if (direction === 'prev' && message.currentVersionIndex > 0) {
    message.currentVersionIndex--;
  } else if (direction === 'next' && message.currentVersionIndex < message.versions.length - 1) {
    message.currentVersionIndex++;
  }
  
  // 同步当前版本内容到消息的主content字段（向后兼容）
  message.content = message.versions[message.currentVersionIndex].content;
};

// 加载历史对话
const loadConversations = async () => {
  try {
    console.log('📡 API调用: 加载历史对话列表');
    const res = await service.get('/ai-chat/conversations', {
      params: {
        page: 1,
        pageSize: 50
      }
    });
    console.log('✅ API响应: 历史对话列表', res.data);
    
    if (res.data && res.data.list) {
      // 替换本地对话历史
      chatHistory.value = res.data.list.map(item => ({
        id: item.id,
        title: item.title,
        messages: [], // 初始为空，切换对话时再加载消息
        isFromServer: true,
        createTime: item.createTime
      }));
      
      // 如果有对话，选择第一个
      if (chatHistory.value.length > 0) {
        switchChat(chatHistory.value[0]);
      }
    }
  } catch (error) {
    console.error("❌ API错误: 加载对话历史失败:", error);
    // 加载失败时使用本地存储
    const savedHistory = localStorage.getItem("chatHistory");
    if (savedHistory) {
      try {
        chatHistory.value = JSON.parse(savedHistory);
        if (chatHistory.value.length > 0) {
          currentChat.value = chatHistory.value[0];
        }
      } catch (e) {
        console.error("❌ 错误: 加载本地历史对话失败:", e);
      }
    }
  }
};

// 加载对话消息
const loadConversationMessages = async (conversationId) => {
  if (!conversationId) return [];
  
  try {
    console.log(`📡 API调用: 加载对话消息, 对话ID=${conversationId}`);
    const res = await service.get(`/ai-chat/conversations/${conversationId}/messages`, {
      params: {
        page: 1,
        pageSize: 100
      }
    });
    console.log(`✅ API响应: 对话消息, 对话ID=${conversationId}`, res.data);
    
    if (res.data && res.data.list) {
      // 转换服务器消息格式为本地格式
      return res.data.list.map(item => ({
        id: item.id,
        role: item.role,
        content: item.content,
        images: item.attachments ? item.attachments.filter(a => a.type === 'image').map(a => a.url) : [],
        files: item.attachments ? item.attachments.filter(a => a.type === 'file').map(a => ({
          name: a.name || '附件',
          url: a.url,
          size: a.size || 0
        })) : [],
        isEditing: false,
        editContent: "",
        versions: [
          {
            id: Date.now(),
            content: item.content,
            isThinking: false,
            showCursor: false,
            searchResults: [],
            timestamp: new Date(item.createTime).getTime()
          }
        ],
        currentVersionIndex: 0
      }));
    }
    return [];
  } catch (error) {
    console.error(`❌ API错误: 加载对话消息失败, 对话ID=${conversationId}:`, error);
    return [];
  }
};

// 使用流式接口接收AI回复
const receiveStreamResponse = (messageId, requestData, isLoggedIn, sessionId) => {
  try {
    // 初始化流式传输状态
    isStreaming.value = true;
    streamingMessageId.value = messageId;
    
    // 找到当前消息
    const message = currentChat.value.messages.find(msg => msg.id === messageId);
    if (!message) {
      console.error('找不到对应的消息:', messageId);
      return;
    }
    
    // 获取当前版本
    const currentVersion = message.versions[message.currentVersionIndex];
    
    // 设置思考状态
    thinkingTimeout.value = setTimeout(() => {
      currentVersion.isThinking = false;
      currentVersion.showCursor = true;
      startCursorBlink(currentVersion);
      
      console.log('🔌 开始流式连接');
      
      // 构建URL和参数
      let url;
      let params = {};
      
      if (isLoggedIn) {
        // 已登录用户使用常规API
        if (message.isRegenerating) {
          // 重新生成消息 - 构建GET请求URL
          url = `/ai-chat/messages/${messageId}/regenerate/stream`;
          params = {
            modelId: requestData.modelId,
            conversationId: currentChat.value.id
          };
        } else {
          // 新消息 - 构建GET请求URL
          url = `/ai-chat/messages/stream`;
          params = {
            modelId: requestData.modelId,
            content: requestData.content || '',
            conversationId: requestData.conversationId
          };
        }
      } else {
        // 未登录用户使用公共API
        url = `/public/ai-chat/messages/stream`;
        params = {
          sessionId,
          modelId: requestData.modelId,
          content: requestData.content || ''
        };
      }
      
      // 创建SSE连接
      sseConnection.value = createSSEConnection(
        url,
        { params, method: 'GET' }, // 使用GET方法
        // 消息处理回调
        (data, eventType) => {
          // 根据不同事件类型处理数据
          switch(eventType) {
            case 'init':
              console.log('流式连接已初始化:', data);
              break;
              
            case 'message':
              // 更新消息内容 - 使用服务器发送的累积内容
              if (data.content !== undefined) {
                // 使用辅助函数更新内容，如果内容更新了，滚动到底部
                if (updateMessageContent(currentVersion, message, data.content)) {
                  scrollToBottom();
                }
              }
              break;
              
            case 'reasoning':
              // 处理思考过程（仅deepseek-r1模型）
              console.log('AI思考过程:', data);
              
              // 如果存在思考内容，显示在界面上
              if (data.content && data.content.trim()) {
                // 如果思考内容字段还不存在，创建它
                if (!currentVersion.reasoningContent) {
                  currentVersion.reasoningContent = '';
                }
                
                // 累积思考内容
                currentVersion.reasoningContent += data.content;
                
                // 更新标志，表示有思考内容
                currentVersion.hasReasoning = true;
                
                // 滚动到底部
                scrollToBottom();
              }
              break;
              
            case 'error':
              console.error('流式响应错误:', data);
              ElMessage.error(data.message || '连接中断');
              finishStreaming();
              break;
              
            case 'end':
              console.log('流式传输完成');
              // 收到完成信号后取消光标闪烁
              currentVersion.showCursor = false;
              finishStreaming();
              break;
              
            case 'keepalive':
              // 保持连接活跃，不需要特殊处理
              break;
              
            default:
              // 默认处理消息内容
              if (data.content !== undefined) {
                // 使用辅助函数更新内容，如果内容更新了，滚动到底部
                if (updateMessageContent(currentVersion, message, data.content)) {
                  scrollToBottom();
                }
              }
              
              // 处理搜索结果
              if (data.searchResults) {
                currentVersion.searchResults = data.searchResults;
              }
              
              // 处理结束信号
              if (data.finished) {
                console.log('🎉 流式传输完成');
                currentVersion.showCursor = false;
                finishStreaming();
              }
              break;
          }
        },
        // 错误处理回调
        (error) => {
          // 仅在开发环境记录错误
          if (process.env.NODE_ENV !== 'production') {
            console.log('连接已结束', error);
          }
          
          // 如果内容为空，说明没有成功获取到任何内容，可以显示提示
          if (!currentVersion.content || currentVersion.content.trim() === '') {
            ElMessage.warning('获取AI回复时遇到问题，请稍后重试');
          }
          
          // 无论如何都要结束流式传输状态
          finishStreaming();
        },
        // 连接关闭回调
        () => {
          console.log('🔌 流式连接已关闭');
          if (isStreaming.value) {
            finishStreaming();
          }
        }
      );
    }, 1500); // 思考1.5秒后开始接收流
  } catch (error) {
    console.error('❌ 建立流式连接失败:', error);
    ElMessage.error('连接AI服务失败，请重试');
    finishStreaming();
  }
};

// 添加一个辅助函数用于处理内容更新
const updateMessageContent = (currentVersion, message, newRawContent) => {
  // 应用内容过滤和修复
  const newContent = filterDebugText(fixRepeatedCharacters(newRawContent || ''));
  const prevContent = currentVersion.content || '';
  
  // 如果内容没有变化，不更新
  if (newContent === prevContent) {
    return false;
  }
  
  // 如果新内容包含旧内容或旧内容为空，直接使用新内容
  if (newContent.includes(prevContent) || prevContent.length === 0) {
    currentVersion.content = newContent;
    message.content = newContent;
    return true;
  } else {
    // 尝试找到增量更新部分
    let commonPrefixLength = 0;
    const minLength = Math.min(prevContent.length, newContent.length);
    
    // 查找共同前缀长度
    for (let i = 0; i < minLength; i++) {
      if (prevContent[i] === newContent[i]) {
        commonPrefixLength++;
      } else {
        break;
      }
    }
    
    // 如果有足够共同前缀，认为是增量内容
    if (commonPrefixLength > prevContent.length * 0.5) {
      currentVersion.content = newContent;
      message.content = newContent;
      return true;
    } else {
      // 直接替换
      currentVersion.content = newContent;
      message.content = newContent;
      return true;
    }
  }
};

// 数据部分添加控制变量
const showAiReasoning = ref(true); // 是否显示AI思考过程

// 保存当前对话到服务器
const saveCurrentChat = async () => {
  if (!currentChat.value || !currentChat.value.isFromServer || !isLoggedIn.value) {
    return;
  }
  
  try {
    // 找到最后一条消息
    const lastMessage = currentChat.value.messages[currentChat.value.messages.length - 1];
    if (lastMessage && lastMessage.role === 'assistant') {
      console.log(`📡 API调用: 保存对话消息, 对话ID=${currentChat.value.id}`);
      
      // 使用最新版本的内容
      const content = lastMessage.versions && lastMessage.versions[lastMessage.currentVersionIndex]
        ? lastMessage.versions[lastMessage.currentVersionIndex].content
        : lastMessage.content;
      
      await service.post(`/ai-chat/conversations/${currentChat.value.id}/messages/save`, {
        role: lastMessage.role,
        content: content
      });
      
      console.log(`✅ API响应: 保存对话消息成功, 对话ID=${currentChat.value.id}`);
    }
  } catch (error) {
    console.error(`❌ API错误: 保存对话消息失败, 对话ID=${currentChat.value.id}:`, error);
  }
};
</script>

<style lang="scss" scoped>
.ai-chat-page {
  @apply dark:bg-gray-900;

  :deep(.el-input__wrapper) {
    @apply dark:bg-gray-800 dark:border-gray-700 dark:text-gray-300;
  }

  :deep(.el-textarea__inner) {
    @apply dark:bg-gray-800 dark:border-gray-700 dark:text-gray-300;

    &::placeholder {
      @apply dark:text-gray-500;
    }
  }

  :deep(.el-button--primary) {
    @apply dark:opacity-90 dark:hover:opacity-100;
  }

  .back-btn {
    @apply hover:bg-gray-100 dark:hover:bg-gray-700 dark:text-gray-200 transition-colors;
  }

  .chat-item {
    @apply dark:hover:bg-gray-700/50;

    &.bg-gray-50 {
      @apply dark:bg-gray-700/50;
    }

    :deep(.el-button--text) {
      @apply dark:text-gray-400 dark:hover:text-gray-300;
    }
  }

  .message-content {
    &.bg-white {
      @apply dark:bg-gray-800 dark:text-gray-100;

      &::before {
        @apply dark:border-r-gray-800;
      }
    }

    .text-gray-500 {
      @apply dark:text-gray-400;
    }
    
    // 用户消息编辑样式
    .user-message-edit {
      @apply text-gray-800;
      
      :deep(.el-textarea__inner) {
        @apply border-gray-300 focus:border-primary-500 focus:ring-2 focus:ring-primary-500/20;
      }
    }
  }

  .tool-button {
    @apply transition-all duration-200;

    &.is-active {
      @apply ring-2 ring-offset-2 dark:ring-offset-gray-900;
    }

    &:hover {
      @apply transform scale-105;
    }
  }

  .feature-card {
    @apply dark:bg-gray-800 dark:text-gray-100 dark:border-gray-700;

    p {
      @apply dark:text-gray-400;
    }
  }

  .example-question {
    @apply dark:bg-gray-800 dark:hover:bg-gray-700 dark:text-gray-300;
  }

  .custom-scrollbar {
    &::-webkit-scrollbar {
      @apply w-2;
    }

    &::-webkit-scrollbar-track {
      @apply bg-transparent;
    }

    &::-webkit-scrollbar-thumb {
      @apply bg-gray-300 dark:bg-gray-600 rounded;

      &:hover {
        @apply bg-gray-400 dark:bg-gray-500;
      }
    }
  }

  :deep(.el-popper.model-selector-popover) {
    @apply dark:!bg-gray-800 dark:!border-gray-700;

    .el-popper__arrow::before {
      @apply dark:!bg-gray-800 dark:!border-gray-700;
    }
  }

  /* 流式传输相关样式 */
  .animate-cursor {
    animation: cursor-blink 0.8s infinite;
  }

  @keyframes cursor-blink {
    0%,
    49% {
      opacity: 1;
    }
    50%,
    100% {
      opacity: 0;
    }
  }

  .loading-dots {
    position: relative;
    width: 16px;
    height: 16px;

    &::before,
    &::after {
      content: "";
      position: absolute;
      width: 4px;
      height: 4px;
      border-radius: 50%;
      background-color: currentColor;
      opacity: 0.6;
    }

    &::before {
      left: 0;
      animation: loading-dots 1.2s infinite;
    }

    &::after {
      right: 0;
      animation: loading-dots 1.2s 0.6s infinite;
    }

    &::after {
      content: "";
      position: absolute;
      width: 4px;
      height: 4px;
      border-radius: 50%;
      background-color: currentColor;
      left: 50%;
      transform: translateX(-50%);
      animation: loading-dots 1.2s 0.3s infinite;
    }
  }

  @keyframes loading-dots {
    0%,
    100% {
      transform: translateY(0);
    }
    50% {
      transform: translateY(-5px);
    }
  }

  /* 搜索结果相关样式 */
  .search-result-card {
    @apply transition-all duration-200;
    
    &:hover {
      @apply shadow-md bg-gray-100 dark:bg-gray-800;
    }
    
    a {
      @apply transition-colors;
    }
  }
}
</style>

<style lang="scss">
// ... existing code ...

.message-item {
  margin-bottom: 24px;
  position: relative;
  
  // 用户消息样式
  &.justify-end {
    .message-content {
      border-top-right-radius: 4px;
      border-bottom-right-radius: 4px;
      border-top-left-radius: 20px;
      border-bottom-left-radius: 20px;
      position: relative;
      
      &:after {
        content: '';
        position: absolute;
        top: 14px;
        right: -8px;
        width: 0;
        height: 0;
        border-style: solid;
        border-width: 8px 0 8px 10px;
        border-color: transparent transparent transparent var(--el-color-primary);
      }
      
      // 编辑模式不显示气泡尾巴
      &.border-primary-300 {
        &:after {
          display: none;
        }
      }
    }
      
    // 用户消息的操作按钮
    .message-actions {
      button {
        color: var(--el-color-white);
        border-color: var(--el-color-primary-light-5);
        background-color: var(--el-color-primary);
          
        &:hover {
          color: var(--el-color-white);
          background-color: var(--el-color-primary-dark-2);
        }
      }
    }
  }
  
  // 助手消息样式
  &:not(.justify-end) {
    .message-content {
      border-top-left-radius: 4px;
      border-bottom-left-radius: 4px;
      border-top-right-radius: 20px;
      border-bottom-right-radius: 20px;
      position: relative;
      
      &:after {
        content: '';
        position: absolute;
        top: 14px;
        left: -8px;
        width: 0;
        height: 0;
        border-style: solid;
        border-width: 8px 10px 8px 0;
        border-color: transparent #fff transparent transparent;
        
        .dark & {
          border-color: transparent var(--el-color-info-light-9) transparent transparent;
        }
      }
    }
  }
  
  // 消息动作按钮样式
  .message-actions {
    opacity: 0;
    transition: opacity 0.2s ease;
    position: absolute;
    bottom: -10px;
    right: 8px;
    z-index: 10;
    background-color: var(--el-color-white);
    border-radius: 20px;
    padding: 3px;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
    
    .dark & {
      background-color: var(--el-color-info-light-9);
    }
    
    button {
      width: 28px;
      height: 28px;
      font-size: 12px;
      margin: 0 2px;
      
      .el-icon {
        font-size: 14px;
      }
      
      &:hover {
        transform: scale(1.1);
      }
      
      &.is-disabled {
        opacity: 0.5;
        transform: none;
      }
    }
  }
  
  &:hover {
    .message-actions {
      opacity: 1;
    }
  }
  
  // 版本信息样式
  .version-info {
    font-size: 12px;
    color: var(--el-color-info);
    margin-right: 8px;
    padding: 2px 6px;
    border-radius: 10px;
    background-color: var(--el-color-info-light-9);
    
    .dark & {
      background-color: var(--el-color-info-dark-2);
      color: var(--el-color-info-light-9);
    }
  }
}

// 工具提示样式优化
.el-tooltip__popper {
  font-size: 12px;
  padding: 6px 10px;
}

// ... existing code ...

// 思考过程样式
.reasoning-content {
  font-size: 0.9rem;
  background-color: rgba(229, 231, 235, 0.5);
  border-left: 3px solid var(--el-color-primary-light-5);
  transition: all 0.3s ease;
  
  .dark & {
    background-color: rgba(55, 65, 81, 0.5);
    border-left: 3px solid var(--el-color-primary-dark-2);
  }
  
  &:hover {
    opacity: 0.9 !important;
  }
}
</style>